:prewrap:

"Nope, you shall not use Future.get(), ever."
-- Stephane Maldini, with a Banking Sector Customer

.Head first with a Java 8 example of some Stream work
[source,java]
----
import static reactor.Environment.*;
import reactor.rx.Streams;
import reactor.rx.BiStreams;

//...

Environment.initialize()

//find the top 10 words used in a list of Strings
Streams.from(aListOfString)
  .dispatchOn(sharedDispatcher())
  .flatMap(sentence ->
    Streams
      .from(sentence.split(" "))
      .dispatchOn(cachedDispatcher())
      .filter(word -> !word.trim().isEmpty())
      .observe(word -> doSomething(word))
  )
  .map(word -> Tuple.of(word, 1))
  .window(1, TimeUnit.SECONDS)
  .flatMap(words ->
    BiStreams.reduceByKey(words, (prev, next) -> prev + next)
      .sort((wordWithCountA, wordWithCountB) -> -wordWithCountA.t2.compareTo(wordWithCountB.t2))
      .take(10)
      .finallyDo(event -> LOG.info("---- window complete! ----"))
  )
  .consume(
    wordWithCount -> LOG.info(wordWithCount.t1 + ": " + wordWithCount.t2),
    error -> LOG.error("", error)
  );
----

[[streams]]
== Coordinating tasks with Streams and Promises

.How Doge can use Reactor-Stream
image::images/streams-overview.png[Stream Overview, width=650, align="center", link="images/streams-overview.png"]


*Reactor Streams* has the following artifacts:

****
* `Stream` and its direct implementations
** Contains *reactive extensions* and other composition API
* `Promise` with a specific https://promisesaplus.com[A+ flavored] API
** Can be transformed back to Stream with `Promise.stream()`
* Static *Factories*, the one-stop-shops to create related components
** `Streams` for `Stream` creation from well-defined data sources (Iterable, nothing, Future, Publisher...)
** `BiStreams` for key-value `Stream<Tuple2>` processing (reduceByKey...)
** `IOStreams` for <<streams.adoc#streams-persistent, Persisting>> and <<core-codec#core-codecs, Decoding>> `Streams`
** `Promises` for single-data-only `Promise`
* `Action` and its direct implementations of every operation provided by the `Stream` following the *Reactive Streams Processor* specification
** Not created directly, but with the Stream API (`Stream.map()` -> MapAction, `Stream.filter()` -> FilterAction...)
* `Broadcaster`, a specific kind of `Action` exposing onXXXX interfaces for dynamic data dispatch
** Unlike <<core-processor#core-processor,Core Processors>>, they will usually not bother with buffering data if there is no subscriber attached
** However the `BehaviorBroadcaster` can replay the latest signal to new Subscribers
****

[NOTE]
Do not confuse `reactor.rx.Stream` with the new JDK 8 `java.util.stream.Stream`. The latter does not offer a Reactive Streams based API nor Reactive Extensions. However, the JDK 8 `Stream` API is quite complete when used with primitive types and Collections. In fact it's quite interesting for JDK 8 enabled applications to mix both JDK and Reactive Streams.

[[streams-basics]]
== Streams Basics
Reactor offers `Stream` or `Promise` based on the Reactive Streams standard to compose statically typed data pipelines.

It is an incredibly useful and flexible component. It's flexible enough to be used to just compose asynchronous actions together like RxJava's `Observable`. But it's powerful enough it can function as an asynchronous work queue that forks and joins arbitrary compositions or other Reactive Streams components coming from one of the other implementors of the standard.footnoteref:[reactive-streams-implementors, including http://akka.io[Akka Streams], http://ratpack.io[Ratpack], and https://github.com/ReactiveX/RxJava[RxJava]].

.There are basically two rough categories of streams
****
* A *hot* `Stream` is unbounded and capable of accepting input data like a sink.
** Think *UI events* such as _mouse clicks_ or realtime *feeds* such as _sensors_, _trade positions_ or _Twitter_.
** Adapted backpressure strategies mixed with the Reactive Streams protocol will apply
* A *cold* `Stream` is bounded and generally created from a fixed collection of data like a `List` or other `Iterable`.
** Think *Cursored Read* such as _IO reads_, _database queries_,
** Automatic Reactive Streams backpressure will apply
****

[NOTE]
====
As seen <<core.adoc#core-dispatchers, previously>>, Reactor uses an `Environment` to keep sets of `Dispatcher` instances around for shared use in a given JVM (and classloader). An `Environment` instance can be created and passed around in an application to avoid classloading segregation issues or the static helpers can be used. Throughout the examples on this site, we'll use the static helpers and encourage you to do likewise. To do that, you'll need to initialize the static `Environment` somewhere in your application.

[source,java]
----
static {
  Environment.initialize();
}
----
====

== Creating Streams and Promises

This is where you start if you are the owner of the data-source and want to just make it Reactive with direct access to various _Reactive Extensions_ and _Reactive Streams_ capacities.

Sometimes it's also a case for expanding an existing *Reactive Stream Publisher* with `Stream` API and we fortunately offer one-shot static API to proceed to the conversion.

Extending existing Reactor `Stream` like we do with `IterableStream`, `SingleValueStream` etc is also an incentive option to create a `Publisher` ready source (Stream implements it) injected with Reactor API.

[IMPORTANT]
====
Streams and Promises are relatively inexpensive, our microbenchmark suite succeeds into creating more than 150M/s on commodity hardware.
Most of the Streams stick to the *Share-Nothing* pattern, only creating new immutable objects when required.

Every operation will return a new instance:
[source, java]
----
Stream<A> stream = Streams.just(a);
Stream<B> transformedStream = stream.map(transformationToB);

Assert.isTrue(transformationStream != stream);
stream.subscribe(subscriber1); //subscriber1 will see the data A unaltered
transformedStream.subscribe(subscriber2); //subscriber2 will see the data B after transformation from A.

//Note theat these two subscribers will materialize independant stream pipelines, a process we also call lifting
----
====

=== From Cold Data Sources

You can create a `Stream` from a variety of sources, including an `Iterable` of known values, a single value to use as the basis for a flow of tasks, or even from blocking structures such as `Future` of `Supplier`.

.Streams.just()
[source,java]
----
Stream<String> st = Streams.just("Hello ", "World", "!"); // <1>

st.dispatchOn(Environment.cachedDispatcher()) // <2>
  .map(String::toUpperCase) // <3>
  .consume(s -> System.out.printf("%s greeting = %s%n", Thread.currentThread(), s)); // <4>
----
<1> Create a `Stream` from a known value but do not assign a default `Dispatcher`.
<2> `.dispatchOn(Dispatcher)` tells the `Stream` which thread to execute tasks on. Use this to move execution from one thread to another.
<3> Transform the input using a commonly-found convention: the map() method.
<4> Produce demand on the pipeline, which means "start processing now". It's an optimize shortcut for `subscribe(Subscriber)` where the Subscriber just requests Long.MAX_VALUE by default.

[IMPORTANT]
Cold Data Sources will be replayed from start for every fresh Subscriber passed to `Stream.subscribe(Subscriber)`, and therefore duplicate consuming is possible.

.Creating pre-determined Streams and Promises
[cols="2,1", options="header"]
|===

|Factory method
|Data Type
2+^.^h|Role

|Streams.<T>empty()
|T
2+|Only emit `onComplete()` once *requested by its Subscriber*.

|Streams.<T>never()
|T
2+|Never emit anything. Useful for keep-alive behaviors.

|Streams.<T, Throwable>fail(*Throwable*)
|T
2+|Only emit `onError(Throwable)`.

|Streams.from(*Future<T>*)
|T
2+|Block the `Subscription.request(long)` on the passed `Future.get()` that might emit `onNext(T)` and `onComplete()` otherwise `onError(Throwable)` for any exception.

|Streams.from(*T[]*)
|T
2+|Emit N `onNext(T)` elements everytime `Subscription.request(N)` is invoked. If N == Long.MAX_VALUE, emit everything. Once all the array has been read, emit `onComplete()`.

|Streams.from(*Iterable<T>*)
|T
2+|Emit N `onNext(T)` elements everytime `Subscription.request(N)` is invoked. If N == Long.MAX_VALUE, emit everything. Once all the array has been read, emit `onComplete()`.

|Streams.range(*long*, _long_)
|Long
2+|Emit a sequence of N `onNext(Long)` everytime `Subscription.request(N)` is invoked. If N == Long.MAX_VALUE, emit everything. Once the inclusive upper bound been read, emit `onComplete()`.

|Streams.just(T, _T, T, T, T, T, T, T_)
|T
2+|An optimization over `Streams.from(Iterable)` that just behaves similarly. Also useful to emit Iterable, Array or Future without colliding with the Streams.from() signatures.

|Streams.generate(*Supplier<T>*)
|T
2+|Emit `onNext(T)` from the producing `Supplier.get()` factory everytime `Subscription.request(N)` is called. The demand N is ignored as only one data is emitted. When a null value is returned, emit `onComplete()`.

|Promises.syncTask(Supplier<T>), Promises.task(, Supplier<T>)
|T
2+|Emit a single `onNext(T)` and `onComplete()` from the producing `Supplier.get()` on the first `Subscription.request(N)` received. The demand N is ignored.

|Promises.success(*T*)
|T
2+|Emit `onNext(T)` and `onComplete()` whenever a `Subscriber` is provided to `Promise.subscribe(Subscriber)`.

|Promises.<T>error(*Throwable*)
|T
2+|Emit `onError(Throwable)` whenever a `Subscriber` is subscribed is provided to `Promise.subscribe(Subscriber)`.

|===

[[streams-reactivestreams]]
=== From Existing Reactive Publishers

Existing Reactive Streams `Publishers` can very well be from other implementations, including the user ones, or from Reactor itself.

The use cases incude:
****
* <<streams.adoc#streams-combine, Combinatory API>> to coordinate various data sources.
* Lazy resource access, reading a Data Source on subscribe or on request, e.g. _Remote HTTP calls_.
* Data-oriented operations such as Key/Value `Tuples Streams`, `Persistent Streams` or Decoding.
* Plain Publisher decoration with `Stream API`
****

.Streams.concat() and Streams.wrap() in action
[source,java]
----
Processor<String,String> processor = RingBufferProcessor.create();

Stream<String> st1 = Streams.just("Hello "); // <1>
Stream<String> st2 = Streams.just("World "); // <1>
Stream<String> st3 = Streams.wrap(processor); // <2>

Streams.concat(st1, st2, st3) // <3>
  .reduce( (prev, next) -> prev + next ) // <4>
  .consume(s -> System.out.printf("%s greeting = %s%n", Thread.currentThread(), s)); // <5>

processor.onNext("!");
processor.onComplete();
----
<1> Create a `Stream` from a known value.
<2> Decorate the core processor with `Stream` API. Note that `Streams.concat()` would have accepted the processor directly as a valid Publisher argument.
<3> Concat the 3 upstream sources (all st1, then all st2, then all st3).
<4> Accumulate the input 2 by 2 and emit the result on upstream completion, after the last complete from st3.
<5> Produce demand on the pipeline, which means "start processing now".

.Creating from available Reactive Streams Publishers
[cols="2,1"]
|===

h|Factory method
|Data Type
2+|Role

2+|

h|Streams.create(*Publisher<T>*)
|T
2+|Only subscribe to the passed `Publisher` when the first `Subscription.request(N)` hits the returned `Stream`.
Therefore it supports malformed Publishers that do not invoke `Subscriber.onSubscribe(Subscription)` as required per specification.

h|Streams.wrap(*Publisher<T>*)
|T
2+|A simple delegating `Stream` to the passed `Publisher.subscribe(Subscriber<T>)` argument. Only supports _well formed_ Publishers correctly using the Reactive Streams protocol:

onSubscribe > onNext\* > (onError \| onComplete)

h|Streams.defer(*Supplier<Publisher<T>>*)
|T
2+|A lazy Publisher access using the level of indirection provided by `Supplier.get()` everytime `Stream.subscribe(Subscriber)` is called.

h|Streams.createWith(*BiConsumer<Long,SubscriberWithContext<T, C>*, _Function<Subscriber<T>,C>, Consumer<C>_)
|T
2+|A Stream generator with explicit callbacks for each `Subscriber` request, start and stop events. similar to `Streams.create(Publisher)` minus the boilerplate for common use.

h|Streams.switchOnNext(*Publisher<Publisher<T>>*)
|T
2+|A Stream alterning in FIFO order between emitted `onNext(Publisher<T>)` from the passed Publisher. The signals will result in downstream Subscriber<T> receiving the next Publisher sequence of `onNext(T)`.
It might interrupt a current upstream emission when the `onNext(Publisher<T>)` signal is received.

h|Streams.concat(*Publisher<T>*, _Publisher<T>*_)

Streams.concat(*Publisher<Publisher<T>>*)
|T
2+|If a Publisher<T> is already emitting, wait for it to `onComplete()` before draining the next pending Publisher<T>. As the name suggests its useful to http://rxmarbles.com/#concat[concat various datasources] and keep ordering right.

h|Streams.merge(*Publisher<T>, Publisher<T>*, Publisher<T>*)

Streams.merge(*Publisher<Publisher<T>>*)
|T
2+|http://rxmarbles.com/#merge[Accept multiple sources] and *interleave* their respective sequence. Order won't be preserved like with `concat`. Demand from a Subscriber will be split between various sources with a minimum of 1 to make sure everyone has a chance to send something.

h|Streams.combineLatest(*Publisher<T1>, Publisher<T2>*, _Publisher<T3-N> x6_, *Function<Tuple2-N, C>*)
|C
2+|http://rxmarbles.com/#combineLatest[Combine most recent emitted elements] from the passed sources using the given aggregating `Function`.

h|Streams.combineLatest(*Publisher<T1>, Publisher<T2>,* _Publisher<T3-N> x6_, *Function<Tuple2-N, C>*)
|C
2+|http://rxmarbles.com/#zip[Combine most recent elements once], every time a source has emitted a signal, apply the given `Function` and clear the temporary aggregate. Effectively it's a flexible _join_ mechanism for multiple types of sources.

h|Streams.join(*Publisher<T>, Publisher<T>*, _Publisher<T> x6_)
|List<T>
2+|A shortcut for zip that only aggregates each complete aggregate in a List matching the order of the passed argument sources.

h|Streams.await(*Publisher<>*, _long, unit, boolean_)
|void
2+|Block the calling thread until `onComplete` of the passed `Publisher`. Optional arguments to tune the timeout and the need to request data as well can be passed. It will throw an exception if the final state is `onError`.

h|IOStreams.<K,V>persistentMap(*String*, _deleteOnExit_)
|V
2+|<<streams.adoc#streams-persistent, A simple shortcut over ChronicleStream constructors>>, a disk-based log appender/tailer. The name argument must match an existing persistent queue under /tmp/persistent-queue\[name\].

h|IOStreams.<K,V>persistentMapReader(*String*)
|V
2+|<<streams.adoc#streams-persistent, A simple shortcut over ChronicleReaderStream constructors>>, a disk-based log tailer. The name argument must match an existing persistent queue under /tmp/persistent-queue\[name\].

h|IOStreams.decode(*Codec<SRC, IN, ?>, Publisher<SRC>*)
|IN
2+|Use <<core.adoc#core-codecs, Codec decoder>> to decode the passed source data type into *IN* type.

h|BiStreams.reduceByKey(*Publisher<Tuple2<KEY,VALUE>>*, _Map<KEY,VALUE>, Publisher<MapStream.Signal<KEY, VALUE>>_, *BiFunction<VALUE, VALUE, VALUE>*)
|Tuple2<KEY,VALUE>
2+|A key-value operation that accumulates computed results for each 2 sequential `onNext(VALUE)` passed to the `BiFunction` argument. The result will be released `onComplete()` only. The options allow to use an existing map store and listen for its events.

h|BiStreams.scanByKey(*Publisher<Tuple2<KEY,VALUE>>*, _Map<KEY,VALUE>, Publisher<MapStream.Signal<KEY, VALUE>>_, *BiFunction<VALUE, VALUE, VALUE>*)
|Tuple2<KEY,VALUE>
2+|A key-value operation that accumulates computed results for each 2 sequential `onNext(VALUE)` passed to the `BiFunction` argument. The result will be released every time just after it has been stored.  The options allow you to use an existing map store and listen for its events.

h|Promises.when(*Promise<T1>, Promise<T2>*, _Promise<T3-N> x6_)
|TupleN<T1,T2,\*?>
2+|Join all unique results from `Promises` and provide for the new `Promise` with the aggregated `Tuple`.

h|Promises.any(*Promise<T>, Promise<T>*, _Promise<T> x6_)
|T
2+|Pick the first signal available among the passed promises and `onNext(T)` the returned `Promise` with this result.

h|Promises.multiWhen(*Promise<T>, Promise<T>*, _Promise<T> x6_)
|List<T>
2+|Join all unique results from `Promises` and provide for the new `Promise` with the aggregated `List`. The difference with the `when` alternative is that the type of promises must match.

|===

=== From Custom Reactive Publishers

Over time, the Reactor user will become more familiar with *Reactive Streams*. That's the perfect moment to start creating custom reactive data-sources!
Usually the implementor would have to respect the specification and verify his work with the *reactive-streams-tck* dependency.
Respecting the contract requires a *Subscription* and a call to *onSubscribe* + a *request(long)* before sending any data.

However Reactor allows some flexibility to only deal with the message passing part and will automatically provide the buffering *Subscription* transparently,
the difference is demonstrated in the code sample below.

.Streams.create and Streams.defer in action
[source,java]
----
final Stream<String> stream1 = Streams.create(new Publisher<String>() {
  @Override
  public void subscribe(Subscriber<? super String> sub) {
    sub.onSubscribe(new Subscription() { // <1>
      @Override
      public void request(long demand) {
        if(demand == 2L){
          sub.onNext("1");
          sub.onNext("2");
          sub.onComplete();
        }
      }

      @Override
      public void cancel() {
        System.out.println("Cancelled!");
      }
    });
  }
});

final Stream<String> stream2 = Streams.create(sub -> {
  sub.onNext("3"); // <2>
  sub.onNext("4");
  sub.onComplete();
});

final AtomicInteger counterSubscriber = new AtomicInteger();

Stream<String> deferred = Streams.defer(() -> {
  if (counterSubscriber.incrementAndGet() == 1) { // <3>
    return stream1;
  }
  else {
     return stream2;
  }
});

deferred
  .consume(s -> System.out.printf("%s First subscription = %s%n", Thread.currentThread(), s));
deferred
  .consume(s -> System.out.printf("%s Second subscription = %s%n", Thread.currentThread(), s));
----
<1> Create a `Stream` from a custom valid `Publisher` which first calls `onSubscribe(Subscription)`.
<2> Create a `Stream` from a custom malformed `Publisher which skips `onSubscribe(Subscription)` and immediately calls `onNext(T)`.
<3> Create a `DeferredStream` that will alternate source Publisher<T> on each `Stream.subscribe` call, evaluating the total number of Subscribers,

Where to go from here? There are plenty of use cases that can benefit from a custom Publisher:

****
* Reactive Facade to convert any IO call with a matching demand and compose: HTTP calls (read N times), SQL queries (select max N), File reads (read N lines)...
* Async Facade to convert any hot data callback into a composable API: AMQP Consumer, Spring MessageChannel endpoint...
****

Reactor offers some reusable components to avoid the boilerplate checking you would have to do without extending exsiting Stream or `PushSubscription`

* Extending `PushSubscription` instead of implementing `Subscription` directly to benefit from terminal state (PushSubscription.isComplete())
* Using `PublisherFactory.create(args)` or `Streams.createWith(args)` to use Functional consumers for every lifecycle step (requested, stopped, started).
* Extending `Stream` instead of implementing `Publisher` directly to benefit from composition API

.Streams.createWith, an alternative to create() minus some boilerplate
[source,java]
----
final Stream<String> stream = Streams.createWith(
  (demand, sub) -> { // <1>
      sub.context(); // <2>
      if (demand >= 2L && !sub.isCancelled()) {
          sub.onNext("1");
          sub.onNext("2");
          sub.onComplete();
      }
  },
  sub -> 0, // <3>
  sub -> System.out.println("Cancelled!") // <4>
);

stream.consume(s -> System.out.printf("%s greeting = %s%n", Thread.currentThread(), s));
----
<1> Attach a request consumer reacting on `Subscriber` requests and passing the demand and the requesting subscriber.
<2> The _sub_ argument is actually a `SubscriberWithContext` possibly assigned with some initial state shared by all request callbacks.
<3> Executed once on start, this is also where we initialize the optional shared context; every request callback will receive 0 from `context()`
<4> Executed once on any terminal event : *cancel()*, *onComplete()* or *onError(e)*.

A good place to start coding the reactive streams way is to simply look at a more elaborate, back-pressure ready <<recipes.adoc#recipe-filestream, File Stream>>.

=== From Hot Data Sources

If you are dealing with an unbounded stream of data like what would be common with a web application that accepts user input via a REST interface, you probably want to use the "hot" variety of `Stream` in Reactor, which we call a link:/docs/api/index.html?reactor/rx/stream/Broadcaster.html[Broadcaster].

To use it, you simply declare a pipeline of composable, functional tasks on the `Broadcaster` and later call link:/docs/api/reactor/rx/stream/Broadcaster.html#onNext-O-[`Broadcaster.onNext(T)`] to publish values into the pipeline.

[NOTE]
`Broadcaster` is a valid `Processor` and `Consumer`. It's possible to `onSubscribe` a Broadcaster as it's also possible to use it as a `Consumer` delegating `Consumer.accept(T)` to `Broadcaster.onNext(T)`.

.Broadcaster.create()
[source,java]
----
Broadcaster<String> sink = Broadcaster.create(Environment.get()); // <1>

sink.map(String::toUpperCase) // <2>
    .consume(s -> System.out.printf("%s greeting = %s%n", Thread.currentThread(), s)); // <3>

sink.onNext("Hello World!"); // <4>
----
<1> Create a `Broadcaster` using the default, shared `RingBufferDispatcher` as the `Dispatcher`.
<2> Transform the input using a commonly-found convention: the map() method.
<3> `.consume()` is a "terminal" operation, which means it produces demand in Reactive Streams parlance.
<4> Publish a value into the pipeline, which will cause the tasks to be invoked.

[IMPORTANT]
Hot Data Sources will never be replayed. Subscribers will only see data from the moment they have been passed to `Stream.subscribe(Subscriber)`.
An exception applies for `BehaviorBroadcaster` (last emitted element is replayed); `Streams.timer()` and `Streams.period()` will also maintain unique timed cursors but will still ignore backpressure.

[IMPORTANT]
Subscribers will see new data N flowing through a Broadcaster every T+I^N^ *only* after they have subscribed at time T.

.Creating flexible Streams
[cols="3,1,1"]
|===

h|Factory
|Input
|Output
3+|Role

3+|

h|Streams.timer(*delay*, _unit, timer_)
|N/A
|Long
3+|Start a Timer on `Stream.subscribe(Subscriber)` call and emit a single `onNext(0L)` then `onComplete()` once the delay is elapsed. Be sure to pass the optional argument `Timer` if there is no current active `Environment`.
`Subscription.request(long)` will be ignored as no backpressure can apply to a scheduled emission.

h|Streams.period(*period*, _unit, timer_)
|N/A
|Long
3+|Start a Timer on `Stream.subscribe(Subscriber)` call and every period of time emit `onNext(N)` where N is an incremented counter starting from 0. Be sure to pass the optional argument `Timer` if there is no current active `Environment`.
`Subscription.request(long)` will be ignored as no backpressure can apply to a scheduled emission.

h|Streams.<T>switchOnNext()
|Publisher<T>
|T
3+|An `Action` which for the record is also a `Processor`. The `onNext(Publisher<T>)` signals will result in downstream `Subscriber<T>` receiving the next Publisher sequence of `onNext(T)`.
 It might interrupt a current upstream emission when the `onNext(Publisher<T>)` signal is received.

h|Broadcaster.<T>create(_Environment, Dispatcher_)
|T
|T
3+|Create a _hot_ bridge between any context allowed to call `onSubscribe`, `onNext`, `onComplete` or `onError` and a composable sequence of these signals under a `Stream`. If no subscribers are actively registered, next signals might trigger a `CancelException`. The optional `Dispatcher` and `Environment` arguments define where to emit each signal. Finally, a Broadcaster can be subscribed any time to a `Publisher`, like a `Stream`.

h|SerializedBroadcaster.create(_Environment, Dispatcher_)
|T
|T
3+|Similar to `Broadcaster.create()` but adds support for concurrent `onNext` from parallel contexts possibly calling the same broadcaster `onXXX` methods.

h|BehaviorBroadcaster.create(_Environment, Dispatcher_)
|T
|T
3+|Simlar to `Broadcaster.create()` but always replays the last data signal (if any) *and* the last terminal signal (`onComplete()`, `onError(Throwable)`) to the new Subscribers.

h|BehaviorBroadcaster.first(*T*, _Environment, Dispatcher_)
|T
|T
3+|Similar to `BehaviorBroadcaster` but starts with a default value T.


h|Streams.wrap(*Processor<I, O>*)
|I
|O
3+|A simple delegating `Stream` to the passed `Publisher.subscribe(Subscriber<O>)` argument. Only supports _well formed_ Publishers correctly using the Reactive Streams protocol:

onSubscribe > onNext\* > (onError \| onComplete)


h|Promises.<T>prepare(*Environment, Dispatcher*)

Promises.ready()
|T
|T
3+|Prepare a `Promise` ready to be called *exactly once* by any external context through `onNext`. Since it's a stateful container holding the result of the fulfilled promise, new subscribers will immediately run on the current thread.

|===


[TIP]
====
For Asynchronous broadcasting, always consider a <<core-processor.adoc#core-processor,Core Processor>> alternative to a `Broadcaster`:
****
* A Broadcaster will trigger a http://projectreactor.io/docs/api/reactor/core/processor/CancelException.html[CancelException] if there are no subscribers. A Core `RingBuffer*Processor` will always deliver buffered data to the first subscriber.
* Some `Dispatcher` types that can be assigned to a `Broadcaster` might not support concurrent `onNext`. Use `RingBuffer*Processor.share()` for an alternative, thread-safe, concurrent `onNext`.
* RingBuffer*Processor supports replaying an event cancelled in-flight by a downstream subscriber if it's still running on the processor thread. A Broadcaster won't support replaying.
* RingBuffer*Processor are faster than their alternative Broadcaster with a RingBufferDispatcher
* RingBufferWorkProcessor supports scaling up with the number of attached subscribers.
* *Broadcaster might be promoted to a `Processor` in 2.1 anyway, achieving the same thing and removing the need for the Reactor user to struggle picking between `Processor` and `Broadcaster`*.
****
====

[[wireup]]
=== Wiring up a Stream

Streams operations -- except for a few exceptions like terminal actions and `broadcast()` -- will never directly subscribe. Instead they will lazily prepare for subscribe.
This is usually called *lift* in Functional programming.

That basically means the Reactor `Stream` user will explicitely call `Stream.subscribe(Subscriber)` or, alternativly, *terminal* actions such as `Stream.consume(Consumer)` to materialize all the registered operations.
Before that `Actions` don't really exist. We use `Stream.lift(Supplier)` to defer the creation of these Actions until `Stream.subscribe(Subscriber)` is explicitely called.

Once everything is wired, each action maintains an upstream `Subscription` and a downstream `Subscription` and the Reactive Streams contract applies all along the pipeline.

[IMPORTANT]
Usually the terminal actions return a `Control` object instead of `Stream`.
This is an component you can use to request or cancel a pipeline without being inside a `Subscriber` context or implementing the full `Subscriber` contract.

.Wiring up 2 pipelines
[source, java]
----
import static reactor.Environment.*;
import reactor.rx.Streams;
import reactor.rx.Stream;
//...

Stream<String> stream = Streams.just("a","b","c","d","e","f","g","h");

//prepare two unique pipelines
Stream<String> actionChain1 = stream.map(String::toUpperCase).filter(w -> w.equals("C"));
Stream<Long> actionChain2 = stream.dispatchOn(sharedDispatcher()).take(5).count();

actionChain1.consume(System.out::println); //start chain1
Control c = actionChain2.consume(System.out::println); //start chain2
//...
c.cancel(); //force this consumer to stop receiving data
----

.After Wiring
image::images/wiringup.png[The 2 Pipelines wired, width=650, align="center", link="images/wiringup.png"]

==== Publish/Subscribe
For *Fan-Out* to subscribers from a unified pipeline, `Stream.process(Processor)`, `Stream.broadcast()`, `Stream.broadcastOn()` and `Stream.broadcastTo()` can be used.

.Sharing an upstream pipeline and wiring up 2 downstream pipelines
[source, java]
----
import static reactor.Environment.*;
import reactor.rx.Streams;
import reactor.rx.Stream;
//...

Stream<String> stream = Streams.just("a","b","c","d","e","f","g","h");

//prepare a shared pipeline
Stream<String> sharedStream = stream.observe(System.out::println).broadcast();

//prepare two unique pipelines
Stream<String> actionChain1 = sharedStream.map(String::toUpperCase).filter(w -> w.equals("C"));
Stream<Long> actionChain2 = sharedStream.take(5).count();

actionChain1.consume(System.out::println); //start chain1
actionChain2.consume(System.out::println); //start chain2
----

.After Wiring a Shared Stream
image::images/broadcast.png[The 3 Pipelines wired, width=650, align="center", link="images/broadcast.png"]


.Operations considered terminal or explicitely subscribing
[cols="2,1"]
|===

h|Stream<T> method
|Return Type
2+|Role

2+|

h|subscribe(*Subscriber<T>*)

_subscribeOn_
|void
2+|Subscribe the passed *Subscriber<T>* and materialize any pending upstream, wired up lazily (the implicit *lift* for non terminal operation). Note a Subscriber must request data if it expects some. The `dispatchOn` and `subscribeOn` alternatives provide for signalling `onSubscribe` using the passed `Dispatcher`.

h|consume(_Consumer<T>,Consumer<T>,Consumer<T>_)

_consumeOn_
|Control
2+|Call `subscribe` with a `ConsumerAction` which interacts with each passed `Consumer`, each time the interest signal is detected. It will `request(Streams.capacity())` to the received `Subscription`, which is `Long.MAX_VALUE` by default, which results in unbounded consuming. The `subscribeOn` and `consumeOn` alternatives provide for signalling `onSubscribe` using the passed `Dispatcher`. Returns a `Control` component to cancel the materialized `Stream`, if necessary. Note that `ConsumeAction` takes care of unbounded recursion if the `onNext(T)` signal triggers a blocking request.

h|consumeLater()
|Control
2+|Similar to `consume` but does not fire an initial `Subscription.request(long)`. The returned `Control` can be used to `request(long)` anytime.

h|tap()
|TapAndControls
2+|Similar to `consume` but returns a `TapAndControls` that will be dynamically updated each time a new `onNext(T)` is signalled or cancelled.


h|batchConsume(*Consumer<T>*, _Consumer<T>, Consumer<T>_, *Function<Long,Long>*)

_batchConsumeOn_
|Control
2+|Similar to `consume` but will request the mapped `Long` demand given the previous demand and starting with the default `Stream.capacity()`. Useful for adapting the demand dynamically due to various factors.

h|adaptiveConsume(*Consumer<T>*, _Consumer<T>, Consumer<T>_, *Function<Stream<Long>,Publisher<Long>>*)

_adaptiveConsumeOn_
|Control
2+|Similar to `batchConsume` but will request the computed sequence of demand `Long`. It can be used to insert flow-control such as `Streams.timer()` to delay demand.

h|next()
|Promise<T>
2+|Return a `Promise<T>` that is actively subscribing to the `Stream`, materializing it, and requesting a single data before unregistering. The immediate next signal `onNext(T)`, `onComplete()` or `onError(Throwable)` will fulfill the promise.

h|toList()
|Promise<List<T>>
2+|Similar to `next()` but will wait until the entire sequence has been produced (`onComplete()`) and pass the accumulated `onNext(T)` in a single `List<T>` fulfilling the returned promise.

h|Stream.toBlockingQueue()
|CompletableBlockingQueue<T>
2+|Subscribe to the `Stream` and return an iterable blocking `Queue<T>` accumulating all `onNext` signals. `CompletableBlockingQueue.isTerminated()` can be used as a condition to exit a blocking `poll()` loop.

h|cache()
|Stream<T>
2+|Turn any Stream into a *Cold* Stream, able to replay all the sequence of signals individually for each Subscriber.
Due to the unbounded nature of the action, you should probably use it only with small(ish) sequences.

h|broadcast()

broadcastOn(Environment, Dispatcher)
|Stream<T>
2+|Turn Any Stream into a *Hot* Stream. This will prevent pipeline duplication by immediately materializing the `Stream` and be ready to publish the signal to N Subscribers downstream.
The demand will be aggregated from all child Subscribers.

h|broadcastTo(*Subscriber<T>*)
|Subscriber<T>
2+|An alternative to `Stream.subscribe` which allows method chaining since the returned instance is the same as the passed argument.

h|process(*Processor<T, O>*)
|Stream<O>
2+|Similar to broadcast() but accept any given `Processor<T, O>`. A perfect place to introduce <<core-processor.adoc#core-processor, Core Processors>> !


|===

[[stream-capacity]]
=== Setting Capacity

The Reactive Streams standard encourages application developers to set reasonable limits on in-flight data. This prevents components from becoming inundated with more data than they can handle, which causes unpredictable problems throughout an application. One of the core concepts of Reactive Streams is that of "backpressure", or the ability of a pipeline to communicate to upstream components that it can only handle a fixed number of items at a time. A useful term to describe this process of queueing and requesting small chunks of a large volume of data is "microbatching".

Within a Reactor `Stream`, it's possible to microbatch items to limit the amount of data in-flight at any given time. This has distinct advantages in a number of ways, not the least of which is that it limits exposure to data loss by preventing the system from accepting more data than it can afford to lose if the system was to crash.

To limit the amount of data in-flight in a `Stream`, use the link:/docs/api/reactor/rx/Stream.html#capacity-long-[`.capacity(long)`] method.

.Streams.just()
[source,java]
----
Stream<String> st;

st
  .dispatchOn(sharedDispatcher())
  .capacity(256) // <1>
  .consume(s -> service.doWork(s)); // <2>
----
<1> Limit the amount of data in-flight to no more than 256 elements at a time.
<2> Produce demand upstream by requesting the next 256 elements of data.

[WARNING]
`capacity` will not affect `consume` actions if the current Stream dispatcher set with `dispatchOn` is a `SynchronousDispatcher.INSTANCE` (default if unset).

[TIP]
We leave as an exercise to the *Reactor User* to study the benefit of setting capacity vs computing dynamic demand with `Stream.adaptiveConsume` or a custom `Subscriber`.

=== Functional Composition

Similar to many other functional libraries, Reactor provides a number of useful methods for composing functions on a `Stream`. You can passively observe values, transform them from one kind to another, filter out values you don't want, buffer values until a size or time trigger is tripped, and many other useful operations.

[IMPORTANT]
These operations are called `Actions`, and they will not <<streams.adoc#wireup,wire up the `Stream` directly>>. They are available on any `Stream` instance, which means <<streams.adoc#streams-basic,you should have one by this stage>>.

****
* `Actions` are `onSubscribe()` in declarative order (left to right), so `stream.actionA().actionB()` will execute actionA first then actionB.
** `onSubscribe()` runs on the parent `Publisher` thread context which can be altered by `subscribeOn(Dispatcher)` for instance.
* `Actions` `subscribe()` in inverse declarative order (right to left). Whenever `subscribe` is excplicitely called at the end of the pipeline, `subscribe()` propagates backward.
** `subscribe()` synchronously propagates back which might affect stack size use. If that becomes an issue, use a delegate `Processor` that runs `subscribe()` on a `Environment.tailRecurse()` dispatcher. Then `process()` it at any point of the chain.
****

==== Observe

If you want to passively observe data as it passes through the pipeline, then use the `.observe(Consumer)` methods and other `reactor.rx.action.passive` actions.
To observe values, use link:/docs/api/reactor/rx/Stream.html#observe-reactor.fn.Consumer-[.observe(Consumer<? super T>)]. To observe errors without dealing with them definitively, use link:/docs/api/reactor/rx/Stream.html#observeError-java.lang.Class-reactor.fn.BiConsumer-[.observe(Class<? extends Throwable>, BiConsumer<Object,? extends Throwable>)]. To observe the Reactive Streams complete signal, use link:/docs/api/reactor/rx/Stream.html#observeComplete-reactor.fn.Consumer-[.observeComplete(Consumer<Void>)]. To observe the cancel signal, use link:/docs/api/reactor/rx/Stream.html#observeCancel-reactor.fn.Consumer-[.observeCancel(Consumer<Void>)]. To observe the Reactive Streams subscribe signal, use link:/docs/api/reactor/rx/Stream.html#observeSubscribe-reactor.fn.Consumer-[.observeSubscribe(Consumer<? super Subscription<T>>)].

.observe(Consumer<T>)
[source,java]
----
Stream<String> st;

st.observe(s -> LOG.info("Got input [{}] on thread [{}}]", s, Thread.currentThread())) // <1>
  .observeComplete(v -> LOG.info("Stream is complete")) // <2>
  .observeError(Throwable.class, (o, t) -> LOG.error("{} caused an error: {}", o, t)) // <3>
  .consume(s -> service.doWork(s)); // <4>
----
<1> Passively observe values passing through without producing demand.
<2> Run once all values have been processed and the `Stream` is marked complete.
<3> Run any time an error is propagated.
<4> Produce demand on the pipeline and consume any values.

==== Filter

It's possible to filter items passing through a `Stream` so that downstream actions only see the data you want them to see. Filtering actions can be found under the `reactor.rx.action.filter` package.
The most popular one is the link:/docs/api/reactor/rx/Stream.html#filter-reactor.fn.Predicate-[`.filter(Predicate<T>)`] method.

[NOTE]
Unmatched data will trigger a `Subscription.request(1)` if the stream is actually not unbounded with a previous demand of Long.MAX_VALUE.

.filter(Predicate<T>)
[source,java]
----
Stream<String> st;

st.filter(s -> s.startsWith("Hello")) // <1>
  .consume(s -> service.doWork(s)); // <2>
----
<1> This will only allow values that start with the string `'Hello'` to pass downstream.
<2> Produce demand on the pipeline and consume any values.

==== Limits

A specific application of filters is for setting limits to a `Stream`. Limiting actions can be found under the `reactor.rx.action.filter` package.
There are various ways to tell a Stream<T> its boundary in time, in size and/or on a specific condition.
The most popular one is the link:/docs/api/reactor/rx/Stream.html#take-long-[`.take(long)`] method.


.Stream.take(long)
[source,java]
----
Streams
  .range(1, 100)
  .take(50) // <1>
  .consume(
    System.out::println,
    Throwable::printStackTrace,
    avoid -> System.out.println("--complete--")
  );
----
<1> Only take the 50 first elements then cancel upstream and complete downstream.

==== Transformation

If you want to actively transform data as it passes through the pipeline, then use `.map(Function)` and other `reactor.rx.action.transformation` actions.
The most popular transforming action is link:/docs/api/reactor/rx/Stream.html#map-reactor.fn.Function-[.map(Function<? super I, ? extends O>)].
A few other `Actions` depend on transforming data, especially <<streams.adoc#streams-combine,Combinatory operations>> like `flatMap` or `concatMap`.

.Stream.map(Function<T,V>)
[source,java]
----
Streams
  .range(1, 100)
  .map(number -> ""+number) // <1>
  .consume(System.out::println);
----
<1> Transform each Long into a String.

[[stream-flatmap]]
==== (A)Sync Transformation: FlatMap, ConcatMap, SwitchMap

If you want to execute a distinct pipeline `Stream<V>` or `Publisher<V>` given an actual input data, you can use combinatory actions such as `.flatMap(Function)` and other `reactor.rx.action.combination` actions.

To transform values into a distinct, possibly asynchronous `Publisher<V>`, use link:/docs/api/reactor/rx/Stream.html#map-reactor.fn.Function-[.flatMap(Function<? super I, ? extends Publisher<? extends O>)].
The returned `Publisher<V>` will then be *merged* back to the main flow signaling `onNext(V)`. They are properly removed from the merging action whey they complete.
The difference between flatMap, concatMap and switchOnMap is the *merging strategy*, respectively *Interleave*, *Fully Sequential* and *Partially Sequential* (interrupted by `onNext(Publisher<T>)`).

[IMPORTANT]
The downstream request is split (minimum 1 by merged Publisher)

.Stream.flatMap(Function)
[source,java]
----
Streams
  .range(1, 100)
  .flatMap(number -> Streams.range(1, number).subscribeOn(Environment.workDispatcher()) ) // <1>
  .consume(
    System.out::println, <2>
    Throwable::printStackTrace,
    avoid -> System.out.println("--complete--")
  );
----
<1> Transform any incoming number into a range of 1-N number merged back and executed on the given Dispatcher.

[[streams-blocking]]
==== Blocking and Promises

Blocking is considered an anti-pattern in *Reactor*. That said, we do offer an appropriate API (Ah AH!) for integration with legacy operations and for testing support.

The Promise API offers a range of *stateful actions* which inspect the current *ready|error|complete* state and, if fulfilled, immediately calls the wired action.

.Stream.toList()
[source,java]
----
Promise<List<Long>> result = Streams
  .range(1, 100)
  .subscribeOn(Environment.workDispatcher())
  .toList(); // <1>

System.out.println(result.await()); // <2>
result.onSuccess(System.out::println); // <3>
----
<1> Consume the entire sequence on the dispatcher thread given in `subscribeOn(Dispatcher)` operation.
<2> Block (default 30 Seconds) until `onComplete()` and print only `onNext(List<Long>)`; or, if `onError(e)`, wrap as RuntimeException and re-raise.
<3> Since the promise is already fulfilled, `System.out.println()` will run immediately on the current context.

.Waiting for a Stream or Promise
|===

h|Functional API or Factory method
^.^a|*Role*

|

h|Streams.await(Publisher<?>)
|Block until the passed Publisher `onComplete()` or `onError(e)`, bubbling up the eventual exception.

h|Stream.next() 

_with_ Promise.await(), Promise.get()...
|Capture in a Promise the immediate next signal only and `onComplete()` if the signal was a data. `get()` can be used to touch but not wait on the promise to fulfill.

h|Stream.toList()

_with_ Promise.await(), Promise.get()...
|Similar to `next()` but capture the full sequence in a List<T> to fulfill the `Promise<List<T>>` returned.

h|Stream.toBlockingQueue()
|Subscribe to the `Stream` and return an iterable blocking `Queue<T>` accumulating all `onNext` signals. `CompletableBlockingQueue.isTerminated()` can be used as a condition to exit a blocking `poll()` loop.

h|Wiring up Synchronous Streams
|It's not specific to any API, but if the current Stream is dispatched on a `SynchronousDispatcher`, it is actually blocking when a *terminal* action is starting, such as `consume()`.

|===

[[streams-multithreading]]
== Understanding the threading model

One common purpose for *Reactive Streams* and *Reactive Extensions* is to be unopinionated about threading behavior *thanks to the signal callbacks*.
Streams are all about *it will be executed at some point between now and some time T*. Non-concurrent signals may also preserve `Subscriber` from concurrency access (share-nothing),
however signals and requests can run on 2 asymmetric threads.

By default the `Stream` is assigned with a `SynchronousDispatcher` and will inform its immediate child `Actions` via `Stream.getDispatcher()`.

[IMPORTANT]
Various `Stream` factories, the `Broadcaster`, the `Stream.dispatchOn`  and the terminal `xxxOn` methods might alter the default `SynchronousDispatcher`.

.It is fundamental to understand the three major thread switchs available in Reactor Stream:
****
* The `Stream.dispatchOn` action is the only one available under `Stream` that will be dispatching *onError*, *onComplete* and *onNext* signals on the given `Dispatcher`. 
** Since an action is a `Processor` it doesn't support concurrent `Dispatcher` such as `WorkQueueDispatcher`.
** `request` and `cancel` will run on the dispatcher as well if in its context already. Otherwise it will execute after the current dispatch ends.
* The `Stream.subscribeOn` action will be executing *onSubscribe* only on the passed dispatcher.
** Since the only time the passed `Dispatcher` is called is *onSubscribe*, any dispatcher can be used including the concurrent ones such as `WorkQueueDispatcher`.
** The first `request` might still execute in the *onSubscribe* thread, for instance with `Stream.consume()` actions.
* Attaching a `Processor` via `Stream.process` for instance can affect the thread too. The `Processor` such as `RingBufferProcessor` will run the `Subscribers` on its managed threads. 
** `request` and `cancel` will run on the processor as well if in its context already.
** `RingBufferWorkProcessor` will only dispatch *onNext* signals to one `Subscriber` at most unless it has cancelled in-flight (replay to a new Subscriber).
****

Since the common contract is to start requesting data *onSubscribe*, `subscribeOn` is an efficient tool to scale-up streams, particulary unbounded ones.
If a `Subscriber` requests *Long.MAX_VALUE* in *onSubscribe*, it will then be the only request executed and it will run on the dispatcher assigned in `subscribeOn`.
This is the default behaviour for unbounded `Stream.consume` actions.

.Jumping between threads with an unbounded demand
[source,java]
----
Streams
  .range(1, 100)
  .dispatchOn(Environment.sharedDispatcher()) // <2>
  .subscribeOn(Environment.workDispatcher()) // <1>
  .consume(); // <3>
----
<1> Assign an *onSubscribe* work queue dispatcher.
<2> Assign a signal *onNext, onError, onComplete* dispatcher.
<3> Consume the `Stream` *onSubscribe* with `Subscription.request(Long.MAX)`

.subscribeOn and dispatchOn/process with an unbounded Subscriber
image::images/longMaxThreading.png[Unbounded threading, width=600, align="center", link="images/longMaxThreading.png"]

However, `subscribeOn` is less useful when more than 1 request will be involved, like in step-consuming with `Stream.capacity(n)`.
The only request executed possibly running on the dispatcher assigned in `subscribeOn` is the *first one*.

.Jumping between thread with a bounded demand 1
[source,java]
----
Streams
  .range(1, 100)
  .process(RingBufferProcessor.create()) // <2>
  .subscribeOn(Environment.workDispatcher()) // <1>
  .capacity(1); // <3>
  .consume(); // <4>
----
<1> Assign an *onSubscribe* work queue dispatcher. Note that it is placed after process as the subscribeOn will run on the ringBuffer thread on subscriber and we want to alter it to the work dispatcher.
<2> Assign an async signal *onNext, onError, onComplete* processor. Similar to `dispatchOn` behavior.
<3> Assign a `Stream` capacity to 1 so the downstream action adapts
<4> Consume the `Stream` *onSubscribe* with `Subscription.request(1)` and after every 1 *onNext*.

.subscribeOn and dispatchOn/process with an bounded (demand N < Long.MAX) Subscriber
image::images/nThreading.png[Bounded threading, width=600, align="center", link="images/nThreading.png"]

[[streams-microbatching]]
== MicroBatching

"Better trade your unused CPU and Memory for your overused Latency"
-- Klingon Proverb

After one or two reads of the <<streams.adoc#streams-basics,101 Stream crash intro>>, you courageous hacker are ready for some _quick ROI_.
In effect dispatching efficiently is far away from the only item to check in the *way of millions messages per sec todo list*.

A common issue in *Distributed Systems* lies in the latency cost over indivudual vs buffered IO writes.
When such situation arises, *MicroBatching* or _small chunk-processing_ is the action to group individual data operations.
Behind the term `Micro` hides a more concrete behavior named *In Memory*. Since the Speed of Light is still a limitation of systems today, main memory remains cheaper to read than *disk*.

====
Latency Comparison Numbers
--------------------------
L1 cache reference                            0.5 ns
Branch mispredict                             5   ns
L2 cache reference                            7   ns             14x L1 cache
Mutex lock/unlock                            25   ns
Main memory reference                       100   ns             20x L2 cache, 200x L1 cache
Compress 1K bytes with Zippy              3,000   ns
Send 1K bytes over 1 Gbps network        10,000   ns    0.01 ms
Read 4K randomly from SSD*              150,000   ns    0.15 ms
Read 1 MB sequentially from memory      250,000   ns    0.25 ms
Round trip within same datacenter       500,000   ns    0.5  ms
Read 1 MB sequentially from SSD*      1,000,000   ns    1    ms  4X memory
Disk seek                            10,000,000   ns   10    ms  20x datacenter roundtrip
Read 1 MB sequentially from disk     20,000,000   ns   20    ms  80x memory, 20X SSD
Send packet CA->Netherlands->CA     150,000,000   ns  150    ms

Notes
-----
1 ns = 10-9 seconds
1 ms = 10-3 seconds
* Assuming ~1GB/sec SSD

Credit
------
By Jeff Dean:               http://research.google.com/people/jeff/
Originally by Peter Norvig: http://norvig.com/21-days.html#answers
====

`Streams` are sequences of data, so finding boundaries to cut aggregated buffers is an out-of-the box  API.

.There are two categories for delimitations:
****
* *Buffer* : Concrete boundaries *accumulating* `onNext(T)` inside grouped `List<T>` passed to the child `Subscriber`.
** Used best with external API requiring `Iterable<T>` input argument.
* *Window* : Discrete boundaries *forwarding* `onNext(T)` into distinct `Stream<T>` passed to the child `Subscriber`.
** Used best with accumulators such as `reduce` or any subscriber/action reacting to `onComplete()`.
** Can be combined with `flatMap` or `concatMap` which merge back the individual windows in a common `Stream<T>`
****

=== Into Buffers

Collecting grouped sequences of data `T` into lists `List<T>` serves two main purposes:

****
* Expose a sequence matching the boundary conditions into an `Iterable` structure commonly used by JVM APIs
* Reduce the volume of `onNext(T)` signals, e.g. `buffer(5)` will transform a sequence of 10 elements into a sequence of 2 lists (of 5 elements).
****

[NOTE]
Collecting data incurs an overhead in memory and possibly CPU that should be sized appropriately. Small and timed boundaries are advised to avoid any long lasting aggregates.

[WARNING]
An `Environment` must be initialized if the timed `buffer()` signatures are used without providing the `Timer` argument.


[source,java]
----
long timeout = 100;
final int batchsize = 4;
CountDownLatch latch = new CountDownLatch(1);

final Broadcaster<Integer> streamBatcher = Broadcaster.<Integer>create(env);
streamBatcher
  .buffer(batchsize, timeout, TimeUnit.MILLISECONDS)
  .consume(i -> latch.countDown());


streamBatcher.onNext(12);
streamBatcher.onNext(123);
Thread.sleep(200);
streamBatcher.onNext(42);
streamBatcher.onNext(666);

latch.await(2, TimeUnit.SECONDS);
----

.Chunk processing with Stream buffers (returning Stream<List<T>>):
|===
h|Stream<T> API
^.^a|*Role*

|

h|buffer(_int_)
|Aggregate until `onComplete()` or the given `int` argument is reached which starts over a new aggregation.

h|buffer(*Publisher<?>*, _Supplier<? extends Publisher<?>>_)
|Aggregate until `onComplete()` or when the first `Publisher<?>` argument emits a signal. The optional `Supplier<? extends Publisher<?>>` supplies a sequence whose first signal will end the linked aggregation. That means overlapping (sliding buffers) and disjointed aggregation can be emitted to the child `Subscriber<List<T>>`.

h|buffer(*Supplier<? extends Publisher<?>>*)
|Aggregate until `onComplete()` or in coordination with a provided `Publisher<?>`. The `Supplier<? extends Publisher<?>>` supplies a sequence whose first signal will end the linked aggregation and start a new one immediately. 

h|buffer(*int, int*)
|Aggregate until `onComplete()` or the given *skip* (the second `int` argument) is reached which starts over a new aggregation. The first *size* `int` argument will delimit the maximum numger of aggregated elements by buffer. That means overlapping (sliding buffers) and disjointed aggregation can be emitted to the child `Subscriber<List<T>>`.

h|buffer(*long*, TimeUnit, Timer_)
|Aggregate until `onComplete()` or the elapsed *period* (the first `long` argument) is reached, which starts over a new aggregation. 

h|buffer(*long, long*, TimeUnit, Timer_)
|Aggregate until `onComplete()` or the given *timeshift* (the second `long` argument) is reached. The *timespan* (the first `long` argument) will delimit the maximum numger of aggregated elements by buffer. That means overlapping (sliding buffers) and disjointed aggregation can be emitted to the child `Subscriber<List<T>>`.

h|buffer(*int, long*, _TimeUnit, Timer_)
|A combination of `buffer(int)` *OR* `buffer(long, TimeUnit, Timer)` conditons. It accumulates until the given *size* has been reached or the *timespan* has elapsed.

|===

=== Into Windows

Forwarding grouped sequences of data `T` into a `Stream<T>` serves three main purposes:

****
* Expose a sequence of data `T` to various limited grouped observations and accumulation: metrics, average, flexible aggregate (`Map`, `Tuple`...).
* Parallelizing grouped sequences combined with `dispatchOn` for each generated `Stream<T>` and merging their results back.
* Repeat `onComplete()` for individual grouped sequences, e.g. in <<net.adoc#net-overview,Async IO>> module to delimit a flush.
****


[NOTE]
====
`Stream<T>` windows are slightly less optimized but equivalent aggregating producer than buffer API if combined with the aggregate-all `Stream.buffer()` method:

[source,java]
----
stream.buffer(10, 1, TimeUnit.SECONDS);

//equivalent to
stream.window(10, 1, TimeUnit.SECONDS).flatMap( window -> window.buffer() )
----
====

[WARNING]
An `Environment` must be initialized if the alias for timed `window()` are used without providing the `Timer` argument.

[source,java]
----
//create a list of 1000 numbers and prepare a Stream to read it
Stream<Integer> sensorDataStream = Streams.from(createTestDataset(1000));

//wait for all windows of 100 to finish
CountDownLatch endLatch = new CountDownLatch(1000 / 100);

Control controls = sensorDataStream
  .window(100)
  .consume(window -> {
    System.out.println("New window starting");
    window
      .reduce(Integer.MAX_VALUE, (acc, next) -> Math.min(acc, next))
      .finallyDo(o -> endLatch.countDown())
      .consume(i -> System.out.println("Minimum " + i));
  });

endLatch.await(10, TimeUnit.SECONDS);
System.out.println(controls.debug());

Assert.assertEquals(0, endLatch.getCount());
----

.Chunk processing with Stream (returning Stream<Stream<T>>):
|===
h|Stream<T> API
^.^a|*Role*

|

h|window(_int_)
|Forward to a generated `Stream<T>` until `onComplete()` or the given `int` argument is reached which starts over a new `Stream`.

h|window(*Publisher<?>*, _Supplier<? extends Publisher<?>>_)
|Forward to a generated `Stream<T>` until `onComplete()` or when the first `Publisher<?>` argument emits a signal. The optional `Supplier<? extends Publisher<?>>` supplies a sequence whose first signal will end the linked aggregation. That means overlapping (sliding buffers) and disjointed aggregations can be emitted to the child `Subscriber<Stream<T>>`.

h|window(*Supplier<? extends Publisher<?>>*)
|Forward to a generated `Stream<T>`  until `onComplete()` or in coordination with a provided `Publisher<?>`. The `Supplier<? extends Publisher<?>>` supplies a sequence whose first signal will end the linked `Stream<T>` and start a new one immediately. 

h|window(*int, int*)
|Forward to a generated `Stream<T>`  until `onComplete()` or the given *skip* (the second `int` argument) is reached which starts over a new `Stream<T>`. The *size* (the first `int` argument) will delimit the maximum numger of aggregated elements by buffer. That means overlapping (sliding buffers) and disjointed sequences can be emitted to the child `Subscriber<Stream<T>>`.

h|window(*long*, TimeUnit, Timer_)
|Forward to a generated `Stream<T>` until `onComplete()` or the elpased *period* (the `long` argument) is reached, which starts over a new `Stream<T>`. 

h|window(*long, long*, TimeUnit, Timer_)
|Forward to a generated `Stream<T>`  until `onComplete()` or the given *timeshift* (the second `long` argument) is reached. The *timespan* (the first `long` argument) will delimit the maximum numger of aggregated elements by buffer. That means overlapping (sliding buffers) and disjointed sequenced can be emitted to the child `Subscriber<Stream<T>>`.

h|window(*int, long*, _TimeUnit, Timer_)
|A combination of `buffer(int)` *OR* `buffer(long, TimeUnit, Timer)` conditons. It forwards to a generated `Stream<T>` until the given *size* has been reached or the *timespan* has elapsed.

|===

[[streams-backpressure]]
== Backpressure and Overflow

Backpressure is addressed automatically in many  situations with the *Reactive Streams* contract. If a `Subscriber` doesn't request more than it can actually process (e.g. something other than `Long.MAX_VALUE`), the upstream source can avoid sending too much data. With a "cold" `Publisher` this only works when you can stop reading from source at any time: _How much to read from a socket, How many rows from a SQL query cursor, how many lines from a File, how many elements from an Iterable_...

If the source is *hot*, such as a timer or UI events, or the `Subscriber` might request `Long.MAX_VALUE` on a large dataset, a strategy must be explicitely picked by the developer to deal with *backpressure*. 

.Reactor provides a set of APIs to deal with Hot and Cold sequences:
****
* Uncontrolled sequences (Hot) should be actively managed
** By *reducing* the sequence volume, e.g. "sampling"
** By *ignoring* data when the demand exceeds capacity
** By *buffering* data when the demand exceeds capacity
* Controlled sequences (Cold) should be passively managed
** By *lowering demand* from the `Subscriber` or at any point of the `Stream`
** By *gapping demand* with delayed requests
****

A common example used extensively in the *Reactive Extensions* documentation is the *Marble Diagram*. The dual timeline helps visualize when and what is observed in the `Publisher` or `Stream` and in a `Subscriber` (e.g. an `Action`). We will use these diagrams here to emphasize the demand flow, where usually such a diagram details the nature of the transformation like _map_ or _filter_.

image::images/marble/marble-101.png[Marble Diagrams, width=650, align="center", link="images/marble/marble-101.png"]

*Reactor* will automatically provide for an in-memory overflow buffer when the dispatcher or the capacity differs from one action to another. This will not apply to `Core Processors`, which handle the overflow in their own way. Dispatchers can be re-used and *Reactor* must limit the number of dispatches where it can, hence the in-memory buffer added by `Action` when dispatchers differ. 

[source,java]
----
Streams.just(1,2,3,4,5)
  .buffer(3) // <1>
  //onOverflowBuffer()
  .capacity(2) // <2>
  .consume()


Streams.just(1,2,3,4,5)
  .dispatchOn(dispatcher1) // <3>
  //onOverflowBuffer()
  .dispatchOn(dispatcher2) // <4>  
  .consume()  
----
<1> The buffer operation set capacity(3)
<2> consume() or any downstream action is set with capacity(2), an implicit onOverflowBuffer() is added
<3> A first action running on dispatcher1
<4> A second action running on a different dispatcher2, an implicit onOverflowBuffer() is added

Ultimately the `Subscriber` can request data one by one, limiting the in-flight data to one element all along the pipeline and requesting one more after each successful `onNext(T)`. The same behavior can be obtained with `capacity(1).consume(...)`.

[source,java]
----
Streams.range(1,1000000)
  .subscribe(new DefaultSubscriber<Long>(){ // <1>
    Subscription sub;
    
    @Override
    void onSubscribe(Subscription sub){
      this.sub = sub;
      sub.request(1); // <2>
    }

    @Override
    void onNext(Long n){
      httpClient.get("localhost/"+n).onSuccess(rep -> sub.request(1)); // <3>
    }
  );
----
<1> Use a `DefaultSubscriber` to avoid implementing all `Subscriber` methods.
<2> Schedule a first demand request after keeping a reference to the subscription.
<3> Use <<net-http.adoc#net-http101, Async HTTP API>> to request more only on successful GET. That will naturally propagate the latency information back to the `RangeStream` `Publisher`. One can imagine then measuring the time difference between two requests and how that gives an interesting insight into the processing and IO latency.

.Controlling the volume of in-flight data
|===

h|Stream<T>
|Role

|

h|subscribe(*Subscriber<T>*)
|A custom `Subscriber<T>` will have the flexibility to request whenever it wishes. It's best to change the size these requests if the `Subscriber` uses blocking operations.

h|capacity(*long*)
|<<streams.adoc#stream-capacity, Set the capacity>> to this `Stream<T>` and all downstream actions.

h|onOverflowBuffer(_CompletableQueue_)
^.^a|Create or use the given `CompletableQueue` to store the overflow elements. Overflow occurs when a `Publisher` sends more data than a `Subscriber` has actually requested. Overflow will be drained over the next calls to `request(long)`.

image::images/marble/marble-overflowbuffer.png[onOverflowBuffer(), width=500, align="center", link="images/marble/marble-overflowbuffer.png"]

h|onOverflowDrop()
^.^a|Ignore the overflowed elements. Overflow occurs when a `Publisher` sends more data than a `Subscriber` has actually requested. Overflow will be drained over the next calls to `request(long)`.

image::images/marble/marble-overflowdrop.png[onOverflowDrop(), width=500, align="center", link="images/marble/marble-overflowdrop.png"]

h|throttle(*long*)
^.^a|Delay downstream `request(long)` and periodically decrement the accumulated demand one by one to request upstream.

image::images/marble/marble-throttle.png[throttle(delay), width=500, align="center", link="images/marble/marble-throttle.png"]

h|requestWhen(*Function<Stream<Long>, Publisher<Long>>*)
^.^a|Pass any downstream `request(long)` to `Stream<Long>` sequence of requests that can be altered and returned using any form of `Publisher<Long>`. The `RequestWhenAction` will subscribe to the produced sequence and immiately forward `onNext(Long)` to the upstream `request(long)`. It behaves similarly to `adaptiveConsume` but can be inserted at any point in the `Stream` pipeline.

image::images/marble/marble-requestwhen.png[requestWhen(requestMapper), width=500, align="center", link="images/marble/marble-requestwhen.png"]

h|batchConsume(*Consumer<T>*, _Consumer<T>, Consumer<T>_, *Function<Long,Long>*) 

_batchConsumeOn_
|Similar to `consume` but will request the mapped `Long` demand given the previous demand and starting with the default `Stream.capacity()`. Useful for adapting the demand from various factors.

h|adaptiveConsume(*Consumer<T>*, _Consumer<T>, Consumer<T>_, *Function<Stream<Long>,Publisher<Long>>*), 

_adaptiveConsumeOn_
|Similar to `batchConsume` but will request the computed sequence of demand `Long`. It can be used to insert flow-control such as `Streams.timer()` to delay demand.  The `AdaptiveConsumerAction` will subscribe to the produced sequence and immediately forwards `onNext(Long)` to the upstream `request(long)`.

h|process(*Processor<T, ?>*)
|Any `Processor` can also take care of transforming the demand or buffer. It is worth checking into the behavior of the specific `Processor` implementation in use.

h|_All_ filter(_arguments_), take(_arguments_), takeWhile(_arguments_)...
|All limit operations can be used to proactively limit the volume of a `Stream`.

h|buffer(_arguments_), reduce(_arguments_), count(_arguments_)...
|All aggregating and metrics operations can be used to proactively limit the volume of a `Stream`.

h|_All_ sample(_arguments_), sampleFirst(_arguments_)
|Reduce the volume of a `Stream<T>` by selecting the last (or the first) `onNext(T)` signals matching the given conditions. These conditions can be timed, sized, timed or sized, and interactive (event-driven).

h|zip(_arguments_), zipWith(_arguments_)
|Reduce the volume of N `Stream<T>` to the least signals producing zipped `Publisher`. The aggregated signals from each `Publisher` can be used to produce a distinct value from the N most recent upstream `onNext(T)`.

|===

[[streams-combine]]
== Combinatory Operations

Combining `Publishers` allows for coordination between multiple *concurrent sequences* of data.
They also serve the purpose of <<streams.adoc#stream-flatmap,asynchronous transformations>>, with the resulting sequences being merged.

Coordinating in a non-blocking way will free the developer from using `Future.get()` or `Promise.await()`, a perilous task when it comes to more than one signal. Being non-blocking means that distinct pipelines won't wait on anything other than `Subscriber` demand. The `Subscriber` requests will be split, with a minimum request of one for each merged `Publisher`.

Merging actions are modeled in `FanInAction` and take care of concurrent signaling with a *thread-stealing* `SerializedSubscriber` proxy to the delegate `Subscriber`. For each signal it will verify if the correct thread is already running the delegate `Subscriber` and rescheduling the signal if not. The signal will then be polled when the busy thread exits `Subscriber` code, possibly running the signal in a different thread than originally produced on.

[WARNING]
<<streams.adoc#streams-backpressure,Reducing the demand volume>> before using `flatMap` might be a good or a bad idea. In effect it doesn't deserve the merging action to subscribe to many parallel `Publisher` if it can't actually process them all. However it limiting the parallel `Publisher` size might also not give a chance to faster `Publisher` pending a request to be delivered. 

.Stream.zipWith(Function)
[source,java]
----
Streams
  .range(1, 100)
  .zipWith( Streams.generate(System::currentTimeMillis), tuple -> tuple ) // <1>
  .consume(
    tuple -> System.out.println("number: "+tuple.getT1()+" time: "+tuple.getT2()) , // <2>
    Throwable::printStackTrace,
    avoid -> System.out.println("--complete--")
  );
----
<1> "Zip" or aggregate the most recent signal from `RangeStream` and the passed `SupplierStream` providing current time
<2> "Zip" produces tuples of data from each zipped `Publisher` in the declarative order (left to right, _stream1.zipWith(stream2)_).

.Combining Data Sources
|===

h|Functional API or Factory method
|Role

|

h|Stream.flatMap(Function<T, Publisher<V>>)
|An <<streams.adoc#stream-flatmap,Async transformation>> is a typed shortcut for `map(Function<T, Publisher<V>>).merge()`. 

The mapping part produces a `Publisher<V>` eventully using the passed data `T`, a common pattern used in <<streams.adoc#streams-microservice, MicroService architecture>>. 

The merging part transforms the sequence of produced `Publisher<V>` into a sequence of `V` by _safely_ subscribing in parallel to all of them. There is no ordering guaranteed, it is *interleaved* sequence of `V`. All merged `Publisher<T>` must complete before the `Subscriber<T>` can complete.

h|Streams.switchOnNext(Publisher<Publisher<T>>)
|A Stream alterning in FIFO order between emitted `onNext(Publisher<T>)` from the passed Publisher. The signals will result in downstream Subscriber<T> receiving the next Publisher sequence of `onNext(T)`.
It might interrupt a current upstream emission when the `onNext(Publisher<T>)` signal is received.
All merged `Publisher<T>` must complete before the `Subscriber<T>` can complete.

h|Streams.merge(Publisher<T>, _Publisher<T> x7_)

Streams.merge(Publisher<Publisher<T>>)

Stream.mergeWith(Publisher<T>)

Stream.merge()
|Transform upstream sequence of `Publisher<T>` into a sequence of `T` by _safely_ subscribing in parallel to all of them. There is no ordering guaranteed, it is *interleaved* sequence of `T`. If the arguments are directly `Publisher<T>` like in `Stream.mergeWith(Publisher<T>)` or `Streams.merge(Publisher<T>, Publisher<T>)`, the `MergeAction` will subscribe to them directly and size more efficiently (known number of parallel upstreams). All merged `Publisher<T>` must complete before the `Subscriber<T>` can complete.

h|Streams.concat(Publisher<T>, _Publisher<T> x7_)

Streams.concat(Publisher<Publisher<T>>)

Stream.concatWith(Publisher)

Stream.startWith(Publisher)
|Similar to `merge()` actions but if a Publisher<T> is already emitting, wait for it to `onComplete()` before draining the next pending Publisher<T>. The sequences will be subscribed in declarative order, from left to right, e.g. `stream1.concatWith(stream2)` or with the argument given in `stream2.startWith(stream1)`.

h|Streams.combineLatest(Publisher<T>, _Publisher<T> x7_, Function<Tuple,V>)

Streams.combineLatest(Publisher<Publisher<T>>, Function<Tuple,V>)
|Combine the most recent `onNext(T)` signal from each distinct `Publisher<T>`. Each signal combines until a future `onNext(T)` from its source `Publisher<T>` replaces it. *After* all `Publisher<T>` have emitted at least one signal, the given combinator function will accept all recent signals and produce the desired combined object. If any `Publisher<T>` completes, the downstream `Subscriber<T>` will complete.

h|Streams.zip(Publisher<T>, _Publisher<T> x7_, Function<Tuple,V>)

Streams.zip(Publisher<Publisher<T>>, Function<Tuple,V>)

Stream.zipWith(Publisher<T>, Function<Tuple2,V>)
|Combine the most recent `onNext(T)` signal from each distinct `Publisher<T>`. Each signal combines only once. *Everytime* all `Publisher<T>` have emitted one signal, the given zipper function will receive them and produce the desired zipped object. If any `Publisher<T>` completes, the downstream `Subscriber<T>` will complete.

h|Streams.join(Publisher<T>, _Publisher<T> x7_)

Streams.join(Publisher<Publisher<T>>)

Stream.joinWith(Publisher<T>)
|A shortcut for `zip` with a predefined zipper function transforming each most recent `Tuple` into a `List<?>`.

|===

[[streams-microservice]]
== MicroServices

The notion of http://martinfowler.com/articles/microservices.html[MicroService] has been an increasingly popular term over the last years. Simply put, we code software components with a focused purpose to encourage _isolation_, _adapted scaling_ and _reuse_. In fact it has been over 30 years we use them:

.An example of microservices in Unix
----
history | grep password
----

Even within the boundaries of the application, we can find the similar concept of functional granularity:

.An example of microservices in _imperative_ Java code
[source, java]
----
User rick = userService.get("Rick");
User morty = userService.get("Morty");
List<Mission> assigned = missionService.findAllByUserAndUser(rick, morty);
----

Of course the application has been widely popular within distributed systems and http://12factor.net[cloud-ready architectures]. When the function is isolated enough, it will depend on N other ones for : Data access, subroutine calls over network, posting into message bus, querying an HTTP REST endpoint etc. This is where troubles begin: *the execution flow is crossing multiple context boundaries*. Relatively latency and failure will start to scale up as the system grows in volume and access.

At this point we can decide to _scale-out_, after all platforms such as http://www.cloudfoundry.org[CloudFoundry] allow for elastic scaling of JVM apps and beyond. But looking at our CPU and memory use, it didn't seem particularly under pressure. Of course it was not, each remote call was just blocking the whole service and preventing concurrent user requests to kick in: They are just parked in some thread pool queue. In the meantime the active request was happily seating for a few milliseconds or more waiting for a remote HTTP call socket to actually write, a delay we call *latency* here.

The same applies to errors, we can make applications more resilient (fallbacks, timeouts, retries...) individually first and not rely on _scaling out_. The classic hope is that a replicate microservice will pick up the requests when a load-balancer will detect the failure:

----
Load Balancer: "are you dead ?"
30 sec later
Load Balancer: "are you dead ?"
30 sec later
Load Balancer: "you're dead !"
MicroService "I'am alive !"
----

[discrete]
==== In a Distributed System, coordination pulls a very long string of issues you wish you have never faced.

A `Publisher` like a `Stream` or a `Promise` is ideal to confront *MicroServices* latency and errors. To improve the situation with better error isolation and non-blocking service calls, code has to be designed with these two constraints in mind. To put on your side the best chances for a successful migration story to a Reactive Architecture, you might prefer to work step by step with quick wins and a few adjustements, test and iterate to the next step.

In this section we're going to cover the basics to create a reactive facade gating each costly remote call, build functional services and make them latency-ready.

.Becoming Reactive with Reactor in 3 steps:
****
. Transform target service calls into _unbounded_ `Stream` or `Promise` return types
** Asynchronous switch for Blocking -> Non Blocking conversion
** Error isolation
. Compose services with the *Reactor Stream* API
** Blocking -> Non Blocking coordination
** Parallelize Blocking calls
. Evolve transformed services to backpressure ready `Stream`
** Chunk processing/reading with bounded access
** Optimize IO operations with Microbatching
****

.Common Actions at play when reading remote resources
|===

h|Functional API or Factory method
|Role

|

h|Streams.create(Publisher), Streams.defer(Supplier), Streams.wrap(Publisher), Streams.generate(Supplier)
|Protecting resource access with a `Publisher` is encouraged. A few <<streams.adoc#streams-basics, Stream factories>> will be particularly useful. The point of creating a `Publisher` is to only `onNext(T)` when the data is ready such as in an IO callback. The read should be triggered by a `Subscriber` request if possible to implement a form of backpressure.

h|Stream.timeout(_arguments_)
|Accessing an external resource, especially remote, should always be limited in time to become more resilient to external conditions such as network partitions. Timeout operations can fallback to another `Publisher` for alternative  service call or just `onError(TimeoutException)`. The timer resets each time a fresh `onNext(T)` is observed.

h|Stream.take(_arguments_)
|Similar to `timeout()`, a need to scope in size an external resource is a common one. It's also useful to fully trigger a pipeline including `onComplete()` processing.

h|Stream.flatMap(Function<T,Publisher<V>)
|An <<streams.adoc#stream-flatmap,Async transformation>> that produces a `Publisher<V>` eventully using the passed data `T`, the ideal place to hook in a call to another service before resuming the current processing.

The sequence of produced `Publisher<V>` will flow in the `Subscriber` into a sequence of `V` by _safely_ subscribing in parallel. 

h|Stream.subscribeOn(Dispatcher), Stream.dispatchOn(Dispatcher), _Core Processors_
a|<<streams.adoc#streams-multithreading,Threading control>> is strategic:

****
* Slow MicroService, low volume or low throughput, e.g. HTTP GET -> `subscribeOn(workQueueDispatcher())` to scale-up concurrent service calls.
* Fast MicroService, high volume or high throughput, e.g. Message Bus -> `dispatchOn(sharedDispatcher())` or `RingBufferXXXProcessor.create()` to scale up message-dispatching.
****

|===

[[streams-microservice-start]]
=== Creating Non-Blocking Services

The first step is to isolate the microservice access. Instead of returning a type `T` or `Future<T>`, we will now start using `Publisher<T>` and specifically `Stream<T>` or `Promise<T>`. The immediate benefit is we don't need to worry anymore about error handling and threading (yet): Errors are propagated in `onError` calls (no bubble up), threading might be tuned later for instance using `dispatchOn`. The additional bonus is we get to make our code more _functional_. It also works nice with Java 8 Lambdas! The target will be to reduce control brackets noise (if, for, while...) and limit more the need for sharing context. Ultimately our target design will encourage streaming over polling large datasets : functions will apply to a sequence, result by result, avoiding loop duplication.

[IMPORTANT]
We prefer to use the implementation artefacts and not `Publisher<T>` to get compile-time access to all the *Reactor Stream* API, unless we want to be API agnostic (a possible case for library developers). `Streams.wrap(Publisher<T>)` will do the trick anyway to convert such generic return type into a proper `Stream<T>`.

.Evolving to reactive microservices, part 1, error isolation and non-blocking in some UserService
[cols="1,1"]
|===
^.^h|The Not So Much Win
^.^h|The Win 
a|

[source,java]
----
//...

public User get(String name) 
throws Exception {
  Result r = userDB.findByName(name);
  return convert(r);
}

public List<User> allFriends(User user) 
throws Exception {    
  ResultSet rs = userDB.findAllFriends(user);
  return convertToList(r);
}

public Future<List<User>> filteredFind(String name) 
throws Exception {    
  User user = get(name);
  if(user == null \|\| !user.isAdmin()){
    return CompletedFuture.completedFuture(null);
  } else {
    //could be in an async thread if wanted
    return CompletedFuture.completedFuture(allFriends(user));
  }
}
----

a|

[source,java]
----
//...

public Promise<User> get(final String name) {
  return Promises
    .task( () -> userDB.findByName(name))
    .timeout(3, TimeUnit.Seconds)
    .map(this::convert)
    .subscribeOn(workDispatcher());
}

public Stream<User> allFriends(final User user)  {    
  return Streams
    .defer(() -> 
      Streams.just(userDB.findAllFriends(user)))
    .timeout(3, TimeUnit.Seconds)
    .map(this::convertToList)
    .flatMap(Streams::from)
    .dispatchOn(cachedDispatcher());
    .subscribeOn(workDispatcher());
}

public Stream<User> filteredFind(String name){
    return get(name)
      .stream()
      .filter(User::isAdmin)        
      .flatMap(this::allFriends);
}
----
2+^.^h|The Result
2+a|

****
* In *all query methods*:
** No more *throws Exception*, its all passed in the pipeline
** No more control logic, we use predefined operators such as map or filter
** Only return `Publisher` (Stream or Promise)
** Limit blocking queries in time with timeout (can be used later for retrying, fallback etc)
** Use a pooled workDispatcher thread On Subscribe
* In *get(name)*:
** Use of typed *single data* Publisher, or `Promise`.
** On Subscribe, call the *task* callback
* In *allFriends(user)*:
** Use `defer()` to invoke the DB query on the *onSubscribe* thread, lazily
** No backpressure strategy yet and we read all the results in one blocking (but async) call
** We convert returned list into a data stream in FlatMap
** Dispatch each signal on an async dispatcher so downstream processing doesn't negatively impact the read
* In *filteredFind(name)*:
** We convert a `Promise` from first get to a Stream with `stream()`
** We only call allFriends() sub-stream if there is a valid user
** The returned Stream<User> resume on the first allFriend() signal
****

|===



[[streams-microservice-compose]]
=== Composing multiple Services Calls

In this second step, we will expand our thinking to the consuming aspect. In a transition phase, keep in mind that `Stream` can be <<streams.adoc#streams-blocking, blocked using operators>>.

There are two issues to address in target: robustness (network partition tolerance etc) and avoiding to wait for a service before processing another:

.Evolving to reactive microservices, part 2, parallel requests and resiliency in some RickAndMortyService
[cols="1,1"]
|===
^.^h|The Not So Much Win
^.^h|The Win 
a|

[source,java]
----
int tries = 0;
while(tries < 3){
  try{
    Future<List<User>> rickFriends = 
      userService.fitleredFind("Rick");

    Future<List<User>> mortyFriends = 
      userService.fitleredFind("Morty");

    System.out.println(
      rickFriends.get(3, TimeUnit.SECONDS)
      .addAll(
        mortyFriends.get(3, TimeUnit.SECONDS))
    );    

  }catch(Exception e){    
    if(tries++ >= 3) throw e;
    Thread.sleep(tries*1000);
  }  
}
----

a|

[source,java]
----
return Streams.merge(
  userService.filteredFind("Rick"),
  userService.filteredFind("Morty")
)
.buffer()
.retryWhen( errors -> 
  errors
  .zipWith(Streams.range(1,3), t -> t.getT2())  
  .flatMap( tries -> Streams.timer(tries) )
)
.consume(System.out::println);
----
2+^.^h|The Result
2+a|

****
* `Streams.merge()` is a non-blocking coordinating operation mixing the two queries in one
* `buffer()` will aggregate all results until completion or error (which we timed previously)
* `retryWhen(Function<Stream<Throwable>, Publisher<?>>` will keep re-subscribing if an error is propagated
** `zipWith` will combine errors with a number of tries up to 3 times
** `zipWith` only return the number of tries from the tuple
** `flatMap` + `Streams.timer(long)` convert each try into a delayed signal (seconds by default)
** Each time a signal is sent by this returned `Publisher`, cancel and subscribe again, until a `onComplete` or `onError` is sent.
** `flatMap` only completes if the internal timer AND the upstream have completed, so after the range of 3 or after errors sequence itself terminates.
****

|===


[[streams-microservice-backpressure]]
=== Supporting Reactive Backpressure

In this last step, we pay a visit to the _UserService.allFriends_ query which is right now polling entire datasets from Database.

.Evolving to reactive microservices, part 3, backpressure in UserService.allFriends
[cols="1,1"]
|===
^.^h|The Win
^.^h|The Epic Win 
a|

[source,java]
----
return Streams
  .defer(() -> 
    Streams.just(userDB.findAllFriends(user)))
  .timeout(3, TimeUnit.Seconds)
  .map(this::convertToList)
  .flatMap(Streams::from)
  .dispatchOn(cachedDispatcher());
  .subscribeOn(workDispatcher());

//Consuming in RickAndMortyService 
//looks like  
stream
  .buffer()
  .consume(System.out::println);
----

a|

[source,java]
----
return Streams
  .createWith(
    (demand, sub) -> {
      ResultSet rs = sub.context();
      long cursor = 0l;
      
      while(rs.hasNext() 
        && cursor++ < demand
        && !sub.isCancelled()){
        
        sub.onNext(rs.next());
      }

      if(!rs.hasNext()){
        sub.onComplete();
      }
    },
    sub -> userDB.findAllFriends(user),
    resultSet -> resultSet.close()
  )
  .timeout(3, TimeUnit.Seconds)
  .map(this::convert)
  .dispatchOn(cachedDispatcher());
  .subscribeOn(workDispatcher());

//Consuming in RickAndMortyService 
//looks like  
stream
  .buffer(5, 200, TimeUnit.MILLISECONDS)
  .consume(System.out::println);

----
2+^.^h|The Result
2+a|

****
* Yes it's more verbose...
* ...But now we stream result by result from the query (could have used pagination with SQL limits as well).
* `Streams.createWith` is a `PublisherFactory` which intercepts requests, start and stop.
** The request consumer gives precisely how many elements a subscriber is ready to receive.
** The request consumer receives a `SubscriberWithContext` delegating to the real `Subscriber`, it gives access to shared context and cancel status.
** We send at most as many individual _Result_ as demanded
** We complete when the query read is fully processed
* Since the data is individual now, convertToList is unecessary, replaced with convert
* The Consuming aspect can start using tools such as `capacity(long)` or `buffer(int)` to batch consume the request 5 by 5.
** As a result the flow will be perceived faster because we don't print after every rows have been read
** We add a time limit to the batch since it might not match with the size
****

[NOTE]
It's important to balance the use of stateful `Iterable<T>` like `List<T>` vs individual streaming `T`. A `List` might incur at some point more latency since we take more time to create it. It's also not playing that well in favor of resiliency since it's a whole batch we can lose if a fatal error occurs. Finally, streaming `T` data makes sizing demand more predictable because we can score individual signals instead of batches of signals.

|===

[[streams-errors]]
== Error Handling

Since error isolation is an important part of the *Reactive* contract, `Stream` API is equipped to build fault tolerant pipelines or service call.

Error isolation comes simply by preventing `onNext`, `onSubscribe` and `onComplete` callbacks to bubble up any exception. Instead they are passed to the `onError` callback and propagated downstream. A few `Action` can react passively or actively on such signal, e.g. `when()` will just observe errors and `onErrorResumeNext()` will switch to a fallback `Publisher`.

****
Inversing the propagation to the consuming side instead of bubbling up to the producer side is the reactive pattern to isolate the data producer from the pipeline errors and keep producers alive and happy.
****

In the end the last `Subscriber` in the chain will be notified with the `onError(t)` callback method. If that `Subscriber` is a `ConsumerAction` for instance, Reactor will re-route an error if no _errorConsumer_ callback has been assigned using `Stream.consume(dataConsumer, errorConsumer)`. The route will trigger the current `Environment` error journal if set, which by default uses SLF4J to log errors.

****
*Reactor* also distinguishes *fatal exceptions* from normal ones, specially during `onSubscribe` process. These exceptions will not be isolated nor passed downstream to the subscriber(s) :

* CancelException 
** Happens if no subscriber is available during `onNext` propagation, e.g. when a subscriber asynchronously cancelled during `onNext` emission
** Use the JVM property *-Dreactor.trace.cancel=true* to enable verbose CancelException and logging in Environment default journal. If not set, Environment will not report these exceptions and there won't be any stacktrace associated neither.
* ReactorFatalException
** Happens when Reactor defines an unrecoverable situation like a scheduling on `Timer` not matching the resolution.
* JVM unsafe exceptions:
** StackOverflowError
** VirtualMachineError
** ThreadDeath
** LinkageError    
****

A good practice as seen in various sections is to set time limits explicitely, so `timeout()` + `retry()` will be your best mates especially to protect against network partitioning. The more data flows in the `Stream` the better it should be able to auto heal to keep a good service availability. 

[IMPORTANT]
In Reactive Streams, at most one error can traverse a pipeline, so you can't really double `onError(e)` a `Subsriber`, in theory. In practice we implemented the _Rx_ operators `retry()` and `retryWhen()` that will cancel/re-subscribe `onError`. That means we still respect the contract as an entire new pipeline will be materialized transparently, with fresh action instances. That also means stateful `Action` like `buffer()` should be used with caution in this scenario since we just de-reference them, their state might be lost. We are working on alternatives, one of them involving external persistence for safe stateful `Actions`. A glimpse of that can be read in the <<streams.adoc#streams-persistent, related section>>.

.Fallback cascade fun
[source,java]
----
Broadcaster<String> broadcaster = Broadcaster.create();

Promise<List<String>> promise =
    broadcaster
        .timeout(1, TimeUnit.SECONDS, Streams.fail(new Exception("another one!"))) // <1>
        .onErrorResumeNext(Streams.just("Alternative Message")) // <2>
        .toList();

broadcaster.onNext("test1");
broadcaster.onNext("test2");
Thread.sleep(1500);

try {
  broadcaster.onNext("test3");
} catch (CancelException ce) {
  //Broadcaster has no subscriber, timeout disconnected the pipeline
}

promise.await();

assertEquals(promise.get().get(0), "test1");
assertEquals(promise.get().get(1), "test2");
assertEquals(promise.get().get(2), "Alternative Message");
----
<1> `TimeoutAction` can fallback when no data is emited for the given time period, but in this case it will just emit another Exception...
<2> ...However, we are lucky to have `onErrorResumeNext(Publisher)` to catch this exception and actually deliver some String payload

Another classic example of fault-tolerant pipeline can be found in <<recipes.adoc#recipes-circuitbreaker, Recipes Section>>.


.Handling errors
|===

h|Stream<T> API
|Role

|

h|when(Class<Throwable>, Consumer<Throwable>)
|Observe specific exception types (and their hierarchy) coming from `onError(Throwable)`.

h|oberveError(Class<Throwable>, BiConsumer<Object,Throwable>)
|Similar to `when` but allows introspection of the failing `onNext(Object)` if any when the exception originally rose.

h|onErrorReturn(_Class<Throwable_, Function<Throwable,T>)
|Provide a fallback signal `T` given an exception matching the passed type otherwise any exception. Commonly use in self-healing services.

h|onErrorResume(_Class<Throwable_, Publisher<T>)
|Provide a fallback sequence of signal `T` given an exception matching the passed type otherwise any exception. Commonly use in self-healing services.

h|materialize() _dematerialize()_
|Transform upstream signal into `Signal<T>`, and treat them as `onNext(Signal<T>)` signals. The immediate effect: it swallows error and completion signals, so it's an effective way to process errors. Once errors are processed we can still run them by transforming the `Signal<T>` into the Reactive Streams right callback via `dematerialize()`.

h|retry(_int, Predicate<Throwable_)
|Cancel/Re-Subscribe the parent `Stream` up to the optional _tries_ argument and matching the passed `Predicate` if provided.

h|retryWhen(Function<Stream<Throwable>,Publisher<?>>)
|Cancel/Re-Subscribe the parent `Stream` when the returned `Publisher` from the passed `Function` emits `onNext(Object)`. The function is called once on subscribe and the generated `Publisher` is subscribed. If the `Publisher` emits `onError(e)` or `onComplete()`, they will be propagated downstream. The `Function` receives a single `Stream` of errors which have occured in any subscribed pipeline. Can be combined with *counting* and *delaying* actions to provide for bounded and exponantial retry strategies.

h|recover(Class<Throwable>, Subscriber<Object>)
|A `retryWhen()` shortcut to re-subscribe parent Publisher if the `onError(Throwable)` matches the given type. On recovery success, the passed `Subscriber` argument will receive the `onNext(Object)` that was the root signal associated with the exception, if any.

h|ignoreError(_Predicate<Throwable>_)
|Transform the matching `onError(Throwable)` signals into `onComplete()`. If no argument has been provided, just transform any error into completion.

h|*throw* CancelException
|That might be the only time we will mention anything related to exception bubbling up. However throwing `CancelException.INSTANCE` in any `onNext(T)` callback is a simple way to *no-ack* an incoming value and inform colocated (within the same thread stack) Publishers like *Core Processor* they might have to re-schedule this data later.

|===

[[streams-persistent]]
== Persisting Stream Data

Not everything has to be in-memory and `Reactor` has started a story to integrate (optional dependency) with https://github.com/OpenHFT/Chronicle-Queue[Java Chronicle].

[source,java]
----
return Streams.merge(
  userService.filteredFind("Rick"),
  userService.filteredFind("Morty")
)
.buffer()
.retryWhen( errors -> 
  errors
  .zipWith(Streams.range(1,3), t -> t.getT2())  
  .flatMap( tries -> Streams.timer(tries) )
)
.consume(System.out::println);
----

.Persisting signals safely
|===

h|Functional API or Factory method
|Role

|

h|Stream.onOverflowBuffer(CompletableQueue)
|

h|IOStreams.persistentMapReader()
|

h|IOStreams.persistentMap()
|

|===

[[streams-analytics]]
== Analytics

Metrics and other stateful operations are fully part of the `Stream` API. Users familiar with `Spark` will recognize some method names in fact. `ScanAction` also offers a popular accumulating functional contract with `reduce()` and `scan()`.

.Playing with metrics and key/value data
[source,java]
----
Broadcaster<Integer> source = Broadcaster.<Integer> create(Environment.get());
long avgTime = 50l;

Promise<Long> result = source
    .throttle(avgTime) // <1>
    .elapsed() // <2>
    .nest() // <3>
    .flatMap(self ->
            BiStreams.reduceByKey(self, (prev, next) -> prev + 1) // <4>
    )
    .sort((a,b) -> a.t1.compareTo(b.t1)) // <5>
    .log("elapsed")
    .reduce(-1L, (acc, next) ->
            acc > 0l ? ((next.t1 + acc) / 2) : next.t1 // <6>
    )
    .next(); // <7>

for (int i = 0; i < 10; i++) {
  source.onNext(1);
}
source.onComplete();
----
<1> Slow down incoming `Subscriber` request to one every ~50 milliseconds, polling waiting data one by one.
<2> Produce a `Tuple2` of *Time delta* and *payload* between 2 signals or between `onSubscribe` and the first signal.
<3> Make the current `Stream` available with `onNext` so we can compose it with a `flatMap`.
<4> Accumulate all data until `onComplete()` in internal `Map` keyed with the `Tuple2.t1` and valued by default with `Tuple2.t2`. Next matching keys will provide the previous value and the incoming new `onNext` in the accumulator `BiFunction`. In this case we only increment the initial payload _1_ by key.
<5> Accumulate all data until `onComplete()` in internal `PriorityQueue` and sort elapsed time _t1_ using the given comparator. After `onComplete()` all data are emitted in order, then complete.
<6> Accumulate until `onComplete` a moving time average defaulting to the first received time.
<7> Take the next and only produced average.

.Output
----
03:14:42.013 [main] INFO  elapsed - subscribe: ScanAction
03:14:42.021 [main] INFO  elapsed - onSubscribe: {push}
03:14:42.022 [main] INFO  elapsed - request: 9223372036854775807
03:14:42.517 [hash-wheel-timer-run-3] INFO  elapsed - onNext: 44,1
03:14:42.518 [hash-wheel-timer-run-3] INFO  elapsed - onNext: 48,1
03:14:42.518 [hash-wheel-timer-run-3] INFO  elapsed - onNext: 49,2
03:14:42.518 [hash-wheel-timer-run-3] INFO  elapsed - onNext: 50,3
03:14:42.518 [hash-wheel-timer-run-3] INFO  elapsed - onNext: 51,3
03:14:42.519 [hash-wheel-timer-run-3] INFO  elapsed - complete: SortAction
03:14:42.520 [hash-wheel-timer-run-3] INFO  elapsed - cancel: SortAction
----

.Operations useful for metrics and other stateful accumulation.
[cols="6,1"]
|===

h|Stream<T> API or Factory method
|Output Type
2+|Role

2+|

h|count()
|Long
2+|Produce the total number of observed `onNext(T)` after observing `onComplete()`. Useful when combined with timed `windows`. Not so useful with sized `windows`, e.g. `stream.window(5).flatMap(w -> w.count())` -> produce 5, awesome.

h|scan(BiFunction<T,T>)
|T
2+|

h|scan(A, BiFunction<A,T>)
|A
2+|

h|reduce(BiFunction<T,T>)
|T
2+|

h|reduce(A, BiFunction<A,T>)
|A
2+|

h|BiStreams.reduceByKey()
|
2+|

h|BiStreams.scanByKey()
|
2+|

h|timestamp()
|Tuple2<Long,T>
2+|

h|elapsed()
|Tuple2<Long,T>
2+|

h|materialize() _dematerialize()_
|Signal<T>
2+|Transform upstream signal into `Signal<T>`, and treat them as `onNext(Signal<T>)` signals. The immediate effect: it swallows error and completion signals, so it's an effective way to count errors and completions if the `Stream` is using `retry` or `repeat` API. Once completion and errors are processed we can still run them by transforming the `Signal<T>` into the Reactive Streams right callback via `dematerialize()`.


|===

[[streams-partition]]
== Partitioning
Partition a `Stream` for concurrent, parallel work.

An important aspect of the functional composition approach to reactive programming is that work can be broken up into discreet chunks and scheduled to run on arbitrary Dispatchers. This means you can easily compose a flow of work that starts with an input value, executes work on another thread, and then passes through subsequent transformation steps once the result is available. This is one of the more common usage patterns with Reactor.


[source,java]
----
DispatcherSupplier supplier1 = Environment.newCachedDispatchers(2, "groupByPool");
DispatcherSupplier supplier2 = Environment.newCachedDispatchers(5, "partitionPool");

Streams
    .range(1, 10)
    .groupBy(n -> n % 2 == 0) // <1>
    .flatMap(stream -> stream
            .dispatchOn(supplier1.get()) // <2>
            .log("groupBy")
    )
    .partition(5) // <3>
    .flatMap(stream -> stream
            .dispatchOn(supplier2.get()) // <4>
            .log("partition")
    )
    .dispatchOn(Environment.sharedDispatcher()) // <5>
    .log("join")
    .consume();
----
<1> Create at most two streams (odd/even) keyed by 0 or 1 and forward the `onNext(T)` to the matching one.
<2> Add one of the pooled dispatchers for the two emitted `Stream` by previous `GroupByAction`. Effectively this is scaling up a stream by using 2 partitions assigned with their own dispatcher. `FlatMap` will merge the result returned by both partitions, running on one of the two threads, but never concurrently.
<3> Create 5 Streams and forward `onNext(T)` to them in a round robin fashion
<4> Use the second dispatcher pool of 5 to assign to the newly generated streams. The returned sequences will be merged.
<5> Dispatch data on the `Environment.sharedDispatcher()`, so neither the first or the second pool. The 5 threads will then be merged under the `Dispatcher` thread

.Output extract
----
03:53:42.060 [groupByPool-3] INFO  groupBy - onNext: 4
03:53:42.060 [partitionPool-8] INFO  partition - onNext: 9
03:53:42.061 [groupByPool-3] INFO  groupBy - onNext: 6
03:53:42.061 [partitionPool-8] INFO  partition - onNext: 4
03:53:42.061 [shared-1] INFO  join - onNext: 9
03:53:42.061 [groupByPool-3] INFO  groupBy - onNext: 8
03:53:42.061 [partitionPool-4] INFO  partition - onNext: 6
03:53:42.061 [shared-1] INFO  join - onNext: 4
03:53:42.061 [groupByPool-3] INFO  groupBy - onNext: 10
03:53:42.061 [shared-1] INFO  join - onNext: 6
03:53:42.061 [groupByPool-3] INFO  groupBy - complete: DispatcherAction
----

.Grouping operations
[cols="6,1"]
|===

h|Stream<T> API
|Output Type
2+|Role

2+|

h|groupBy(Function<T,K>)
|GroupedStream<K,T>
2+|

h|partition(int)
|GroupedStream<K,T>
2+|


h|_All_ window(_arguments_)
|Stream<T>
2+|<<streams.adoc#streams-microbatching, Windows>> are actually for cutting partitions over time, size or coordinated with external signals.


h|process(XXXWorkProcessor)
|T
2+|Since a RingBufferWorkProcessor distributes the signals to each subscribe, it is an efficient alternative to `partition()` when its just about scaling-up, not routing.

|===


[[streams-notrx]]
== Other API beyond Rx

In addition to implementing directly the Reactive Streams, some more `Stream` methods not covered differ or are simply not documented by Reactive Extensions.

.Other methods uncovered in the previous use cases.
[cols="6,1,1"]
|===

h|Stream<T> API
|Input Type
|Output Type
3+|Role

3+|

h|after()
|T
|Void
3+|Only consume `onComplete()` and `onError(Throwable)` signals. 

h|log(_String_)
|T
|T
3+|Use SLF4J and the given category to log each signal.

h|split
|Iterable<T>
|T
3+|Blocking transformation from `Iterable<T>` to as many `onNext(T)` as available.

h|sort(_int_, Comparator<T>)
|T
|T
3+|Accept up to the given size into an in memory `PriorityQueue`, apply the `Comparator<T>` to sort, and emit all its pending `onNext(T)` signals.

h|combine()
|I
|O
3+a|Scan for the most ancient parent or `Action`, from right to left. As a result, it will create a new `Processor` with the input `onXXXX` signals dispatched to the old action and the output `subscribe` delegated to the current action.

Example: 

[source,java]
----
Action<Integer, String> processor = stream
  .filter( i -> i<2 )
  .map(Object::toString)
  .combine();

  processor.consume(System.out::println);
  processor.onNext(1);
  processor.onNext(3);
----

h|keepAlive()
|T
|T
3+|Prevent any `Subscription.cancel()` to propagate from the `Subscriber`.

|Action.debug(), StreamsUtils.debug(Stream)
|A quick
|===
