Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Reactive Spring

Reactive Spring

This workshop explains reactive programming concepts, using Project Reactor and Spring to build asynchronous, non-blocking applications.

Code: https://github.com/mp911de/reactive-spring

Mark Paluch

May 08, 2017
Tweet

More Decks by Mark Paluch

Other Decks in Programming

Transcript

  1. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Reactive Spring
    JAX 2017
    Mark Paluch, Pivotal Software, Inc.
    @mp911de

    View Slide

  2. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    @mp911de
    github.com/mp911de
    paluch.biz
    Mark Paluch

    View Slide

  3. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    What is Reactive
    Programming?

    View Slide

  4. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Imperative
    ! Reactive
    ! Synchronous
    ! Blocking
    ! Non-Blocking
    ! Asynchronous
    ! Actors
    4
    Programming models

    View Slide

  5. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    5
    Understanding imperative
    HttpClient c = …;
    HttpGet get = new HttpGet("https://google.com");
    HttpResponse response = c.execute(get);

    View Slide

  6. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    6
    Understanding imperative
    EntityManager entityManager = …;
    List users = …
    entityManager.getTransaction().begin();
    for (User user : users) {
    entityManager.persist(user);
    }
    entityManager.getTransaction().commit();

    View Slide

  7. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    7
    Understanding imperative
    public void saveUsers() {
    EntityManager entityManager = …;
    List users = …
    entityManager.getTransaction().begin();
    for (User user : users) {
    entityManager.persist(user);
    }
    entityManager.getTransaction().commit();
    }

    View Slide

  8. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    8
    Understanding imperative
    HttpClient c = …;
    for (int i = 0; i < 10; i++) {
    HttpGet get = new HttpGet("https://google.com");
    HttpResponse response = c.execute(get);
    // …
    }

    View Slide

  9. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Use Case: Remote calls with latency
    9
    Request Data access
    Remote data
    service

    View Slide

  10. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Use Case: Remote calls with latency
    9
    Request Data access
    Remote data
    service

    View Slide

  11. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Use Case: Remote calls with latency
    9
    Request Data access
    Remote data
    service
    I/O Wait

    View Slide

  12. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Use Case: Remote calls with latency
    9
    Request Data access
    Remote data
    service
    I/O Wait

    View Slide

  13. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Use Case: Remote calls with latency
    9
    Request Data access
    Remote data
    service
    I/O Wait
    This one is
    waiting

    View Slide

  14. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Use Case: Remote calls with latency
    9
    Request Data access
    Remote data
    service
    I/O Wait
    This one is
    waiting

    View Slide

  15. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Makes assumptions over resource usage
    ! Developers are in charge of resource usage efficiency
    10
    Imperative programming

    View Slide

  16. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Container calls code on a Thread
    ! Call continues until all work is done
    ! Thread is occupied
    ! Thread is released at the end of work
    • Latencies affect duration in which Thread is occupied
    11
    Imperative: Web applications

    View Slide

  17. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Reactive is used to describe event-driven systems
    ! Reactive is used more for scalability and stability than
    for speed
    ! Reacts to resource availability
    12
    What is reactive?

    View Slide

  18. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Use Case: Synchronous fetch model
    13

    View Slide

  19. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Use Case: Synchronous fetch model
    13
    Service
    App
    Data store
    App
    Service

    View Slide

  20. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Use Case: Serve slow clients
    14
    Server

    View Slide

  21. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Use Case: Serve slow clients
    15
    Server

    View Slide

  22. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Use Case: Push message to client
    16
    Server
    Message Broker

    View Slide

  23. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Live (continuous) database queries
    ! UI event handling (Android)
    ! Big Data
    ! Real time analytics
    ! HTTP/2
    17
    Other use cases

    View Slide

  24. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! A form of computer timing control protocol
    ! Starts processing after receiving a signal
    ! Completed eventually
    18
    Asynchronous

    View Slide

  25. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Introduces concurrency
    ! Does not block the caller
    • At least in the first place
    ! Keeps more Threads busy
    19
    Asynchronous

    View Slide

  26. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Unit of execution
    • Runnable
    ! Executor
    • Thread
    • ThreadPool
    20
    Asynchronous: Requirements

    View Slide

  27. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Asynchronous: Future
    21
    AsyncRestTemplate asyncRestTemplate = …
    AsyncCassandraTemplate asyncCassandra = …
    SettableListenableFuture future = new SettableListenableFuture<>();
    asyncRestTemplate.getForEntity("https://slow-service.com", String.class)
    .addCallback(response -> {
    Page page = new Page();
    page.setId(…);
    page.setContent(response.getBody());
    ListenableFuture insertFuture = asyncCassandra.insert(page);
    insertFuture.addCallback(savedPage -> future.set("OK"),
    failure -> future.setException(failure));
    }, failure -> failure -> future.setException(failure));
    return future;

    View Slide

  28. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Asynchronous: Future
    22
    AsyncRestTemplate asyncRestTemplate = …
    AsyncCassandraTemplate asyncCassandra = …
    SettableListenableFuture future = new SettableListenableFuture<>();
    asyncRestTemplate.getForEntity("https://slow-service.com", String.class)
    .addCallback(response -> {
    Page page = new Page();
    page.setId(…);
    page.setContent(response.getBody());
    ListenableFuture insertFuture = asyncCassandra.insert(page);
    insertFuture.addCallback(savedPage -> future.set("OK"),
    failure -> future.setException(failure));
    }, failure -> failure -> future.setException(failure));
    return future;

    View Slide

  29. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Asynchronous: Future
    23
    AsyncRestTemplate asyncRestTemplate = …
    AsyncCassandraTemplate asyncCassandra = …
    SettableListenableFuture future = new SettableListenableFuture<>();
    asyncRestTemplate.getForEntity("https://slow-service.com", String.class)
    .addCallback(response -> {
    Page page = new Page();
    page.setId(…);
    page.setContent(response.getBody());
    ListenableFuture insertFuture = asyncCassandra.insert(page);
    insertFuture.addCallback(savedPage -> future.set("OK"),
    failure -> future.setException(failure));
    }, failure -> failure -> future.setException(failure));
    return future;

    View Slide

  30. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Asynchronous: Future
    24
    AsyncRestTemplate asyncRestTemplate = …
    AsyncCassandraTemplate asyncCassandra = …
    SettableListenableFuture future = new SettableListenableFuture<>();
    asyncRestTemplate.getForEntity("https://slow-service.com", String.class)
    .addCallback(response -> {
    Page page = new Page();
    page.setId(…);
    page.setContent(response.getBody());
    ListenableFuture insertFuture = asyncCassandra.insert(page);
    insertFuture.addCallback(savedPage -> future.set("OK"),
    failure -> future.setException(failure));
    }, failure -> failure -> future.setException(failure));
    return future;

    View Slide

  31. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Say „callback“ to a JavaScript
    developer and he will start crying
    instantaneously!
    – Venkat Subramaniam
    25

    View Slide

  32. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    26
    Using Java types
    Non-
    Blocking
    Streaming Pattern
    Future x Pull
    CompletableFuture x Push
    Stream x Pull
    Iterator x Pull
    Input/OutputStream x Pull

    View Slide

  33. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Available since Java 8
    ! Functional composition
    ! Functional transformation
    27
    Asynchronous: CompletableFuture

    View Slide

  34. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Asynchronous: CompletableFuture example
    28
    CompletableFuture> future = …
    future.thenCompose(response -> {
    Page page = new Page();
    page.setId(…);
    page.setContent(response.getBody());
    return asyncCassandra.insert(page);
    }).thenApply(Page::getId);

    View Slide

  35. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    29
    Concurrency effects
    public static class Test extends Thread {
    boolean keepRunning = true;
    public void run() {
    long count = 0;
    while (keepRunning) {
    count++;
    }
    System.out.println("Thread terminated after cycles: " + count);
    }
    }
    public static void main(String[] args) throws InterruptedException {
    Test t = new Test();
    t.start();
    System.out.println("Started");
    Thread.sleep(1000);
    t.keepRunning = false;
    System.out.println("keepRunning set to false.");
    }

    View Slide

  36. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Understanding the Java Memory Model is hard.
    Getting concurrency right is harder.
    30

    View Slide

  37. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Effects of an async fetch model
    31
    Request I/O


    View Slide

  38. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Effects of an async fetch model
    31
    Request I/O


    View Slide

  39. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Effects of an async fetch model
    31
    Request I/O


    View Slide

  40. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Effects of an async fetch model
    31
    Request I/O


    View Slide

  41. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Effects of an async fetch model
    31
    Request I/O
    Requires
    synchronization


    View Slide

  42. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Effects of an async fetch model
    31
    Request I/O
    Requires
    synchronization
    Still waiting, eh?


    View Slide

  43. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Effects of an async fetch model
    31
    Request I/O
    Requires
    synchronization
    Still waiting, eh?


    View Slide

  44. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Makes assumptions over resource usage
    ! Need a change
    • Change programming model
    32
    Imperative programming

    View Slide

  45. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    We need a different toolset!
    33

    View Slide

  46. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    We need a different toolset!
    34

    View Slide

  47. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Allows building and composing asynchronous applications
    ! Reacts to the availability of resources
    ! Requires a reactive API
    35
    Reactive programming model

    View Slide

  48. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Collaborative initiative to provide a standard for
    asynchronous stream processing with non-blocking back
    pressure.
    ! Co-designed by Twitter, Lightbend, Pivotal, Netflix and many
    others
    ! De-facto interop standard
    ! Java 9: Flow API
    36
    Reactive Streams

    View Slide

  49. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Publisher and Subscriber
    37
    Subscriber
    Publisher
    Subscribe
    Data

    View Slide

  50. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Publisher and Subscriber
    37
    Subscriber
    Publisher
    Subscribe
    Data

    View Slide

  51. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Publisher and Subscriber
    37
    Subscriber
    Publisher
    Subscribe
    Data

    View Slide

  52. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    38
    Distributions
    org.reactivestreams:reactive-streams
    • Publisher
    • Subscriber
    • Subscription
    • Processor
    • Flow.Publisher
    • Flow.Subscriber
    • Flow.Subscription
    • Flow.Processor
    Part of Java 9 in java.util.concurrent

    View Slide

  53. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Apply a wide range of operators: map, split, merge, delay
    RxJava 1 & 2
    Project Reactor
    Akka Streams
    39
    Reactive libraries

    View Slide

  54. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    40
    Reactive APIs on the JVM
    Reactive API
    Reactive Streams

    Type
    Non-Reactive

    Streams Type
    RxJava 1
    Observable

    Single

    Completable
    RxJava 2 Flowable
    Observable

    Single

    Maybe,Completable
    Akka Streams 2
    Source

    Sink

    Flow
    Project Reactor
    Mono

    Flux

    View Slide

  55. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    41
    Reactive APIs on the JVM: Generations
    Reactive API Generation Support
    RxJava 1 2nd Limited back pressure
    RxJava 2 4th
    Reactive Streams +
    operator fusion
    Akka Streams 2 3rd
    Reactive Streams +
    actor fusion
    Project Reactor 4th
    Reactive Streams +
    operator fusion

    View Slide

  56. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Use Reactor if
    • using Java 8
    ! Use RxJava if
    • stuck with Java 6
    • need checked Exceptions in functions
    42
    RxJava 2 or Project Reactor

    View Slide

  57. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! „Volume knob“ for data emission
    ! Communicates demand (capacity) of the subscriber to the
    publisher
    43
    Back pressure

    View Slide

  58. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Request all the data
    ! Now
    44
    Asynchronous fetch model
    AsyncHttpClient c = …;
    for (int i = 0; i < 10; i++) {
    HttpGet get = new HttpGet("https://google.com");
    Future response = c.execute(get);
    // …
    }

    View Slide

  59. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Asynchronous fetch model
    45

    View Slide

  60. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Asynchronous fetch model
    45
    Remote
    App
    Remote Remote
    App can’t keep up
    (Back pressure)

    View Slide

  61. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Asynchronous fetch model
    45
    Remote
    App
    Remote Remote
    App can’t keep up
    (Back pressure)

    View Slide

  62. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Publisher and Subscriber
    46
    Subscriber
    Publisher
    Publish as fast as possible

    View Slide

  63. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    47
    Publisher

    View Slide

  64. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    47
    Publisher
    I/O thread
    push

    View Slide

  65. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Back pressure control
    48
    Subscriber
    Publisher
    Demand

    View Slide

  66. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Back pressure control
    49
    Subscriber
    Publisher
    Demand

    View Slide

  67. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Reactive fetch model
    50

    View Slide

  68. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Reactive fetch model
    50
    Data store
    App

    View Slide

  69. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Reactive fetch model
    50
    Data store
    App
    Data store

    View Slide

  70. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Reactive fetch model
    50
    Data store
    App
    Data store Data store

    View Slide

  71. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Reactive fetch model
    50
    Data store
    App
    Data store Data store Data store
    App

    View Slide

  72. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Reactive fetch model
    50
    Data store
    App
    Data store Data store Data store
    App

    View Slide

  73. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Introduction to
    Project Reactor

    View Slide

  74. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    How do you achieve asynchronous, non-blocking
    processing?
    Without losing your mind?
    52

    View Slide

  75. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    53

    View Slide

  76. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    54

    View Slide

  77. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    55
    List
    Iterator
    Future
    Future>

    View Slide

  78. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    55
    List
    Iterator
    Future
    Future>
    .get()
    for-each .hasNext()

    View Slide

  79. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    55
    List
    Iterator
    Future
    Future>
    .get()
    for-each .hasNext()
    Request thread pulls

    View Slide

  80. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    56
    Publisher

    View Slide

  81. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    56
    Publisher
    Thread
    pushes data

    View Slide

  82. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    57
    Iterable
    Iterator
    Publisher
    Subscriber

    View Slide

  83. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    57
    Iterable
    Iterator
    Publisher
    Subscriber
    vs.

    View Slide

  84. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    58
    Subscriber
    Publisher
    feedback
    push events
    produces consumes
    Relation between Publisher and Subscriber

    View Slide

  85. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    59
    Subscriber
    Publisher
    feedback
    push events
    produces consumes
    interfaces from Reactive Streams spec
    Relation between Publisher and Subscriber

    View Slide

  86. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    60
    Subscriber
    Publisher
    feedback
    0..N elements
    +
    0..1 (complete | error)
    produces consumes
    Signals

    View Slide

  87. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    61
    Subscriber
    Publisher
    push events
    produces consumes
    Demand (Back pressure control)
    Back pressure

    View Slide

  88. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    62
    Subscriber
    Publisher
    push events
    produces consumes
    can I have an
    API though?

    View Slide

  89. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    63
    Subscriber
    Publisher
    push events
    produces consumes

    View Slide

  90. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    64
    Project Reactor 3

    View Slide

  91. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Composing asynchronous & event-based sequences, using
    non-blocking operators
    ! Without sacrifice
    • No callback hell
    • No Futures
    ! End to end Reactive Streams
    65
    Project Reactor

    View Slide

  92. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Duration
    ! CompletableFuture
    ! Stream
    66
    Focus on Java 8

    View Slide

  93. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Project Reactor Types
    67
    Mono
    Flux

    View Slide

  94. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Project Reactor Types
    67
    Mono
    Flux
    0..1..Error
    0..N..Error

    View Slide

  95. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    68
    This is the timeline of the
    Flux. Time flows from left
    to right.
    These are items emitted by
    the Flux.
    This vertical line indicates that the Flux
    has completed successfully.
    These dotted lines and this box
    indicate that a transformation is being
    applied to the Flux. The text inside the
    box shows the nature of the
    transformation.
    If for some reason the Flux terminates
    abnormally, with an error, the vertical line is
    replaced by an X.
    This Flux is the result
    of the transformation.
    operator
    1 2 3 4 5 6
    1 2 3
    Explaining reactive operations

    View Slide

  96. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Explaining reactive operations
    69
    Transformed
    Completion signal
    Error signal
    Emitted element
    Time

    View Slide

  97. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Flux
    70
    These are items emitted by
    the Flux.
    operator
    1 2 3 4 5 6
    1 2 3

    View Slide

  98. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Mono
    71
    This is the eventual item
    emitted by the Mono.
    operator
    1
    1

    View Slide

  99. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    72
    Operators
    an Rx-inspired API
    with a vocabulary of operators similar to RxJava...

    View Slide

  100. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    73
    Operators
    an Rx-inspired API
    ...but not exactly the same

    View Slide

  101. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    74
    Flux/Mono
    generator
    operator
    operator
    operator
    nothing happens
    until you subscribe

    View Slide

  102. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    75
    Flux/Mono
    generator
    Subscriber
    operator
    operator
    operator
    nothing happens
    until you subscribe

    View Slide

  103. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Flux/Mono
    generator
    Subscriber
    operator
    operator
    operator
    Sub
    Sub
    Sub
    per Subscription
    state

    View Slide

  104. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    data
    flows
    Flux/Mono
    generator
    Subscriber
    operator
    operator
    operator
    Sub
    Sub
    Sub

    View Slide

  105. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Reactor is agnostic
    ! Facilitates switching
    ! Schedulers
    78
    Threading (contexts)

    View Slide

  106. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! single: Single-Threaded scheduler
    ! elastic: Grows (unbounded) as needed
    • used for I/O offloading
    ! parallel: Fixed-sized at number of CPU cores
    • Event-Loop
    ! timer: Timed tasks
    79
    Schedulers

    View Slide

  107. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! publishOn
    • switch emission of the Publisher on a thread
    ! subscribeOn
    • make the subscription and request happen on a particular
    thread
    80
    Context switching

    View Slide

  108. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    81
    Flux/Mono
    generator
    operator
    subscribeOn
    operator
    publishOn
    operator
    operator
    Subscriber
    Sub
    Sub
    Sub
    Sub
    Sub
    Sub

    View Slide

  109. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    82
    Flux/Mono
    generator
    operator
    subscribe
    On
    operator
    publish
    On
    operator
    operator
    Subscriber
    Sub
    Sub
    Sub
    Sub
    Sub
    Sub

    View Slide

  110. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    83
    Flux/Mono
    generator
    operator
    subscribeOn
    operator
    publishOn
    operator
    operator
    Subscriber
    Sub
    Sub
    Sub
    Sub
    Sub
    Sub

    View Slide

  111. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    84
    Flux/Mono
    generator
    operator
    subscribeOn
    operator
    publishOn
    operator
    operator
    Subscriber
    Sub
    Sub
    Sub
    Sub
    Sub
    Sub

    View Slide

  112. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    85
    Flux/Mono
    generator
    operator
    subscribeOn
    operator
    publishOn
    operator
    operator
    Subscriber
    Sub
    Sub
    Sub
    Sub
    Sub
    Sub

    View Slide

  113. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    86
    Flux/Mono
    generator
    operator
    subscribeOn
    operator
    publishOn
    operator
    operator
    Subscriber
    Sub
    Sub
    Sub
    Sub
    Sub
    Sub

    View Slide

  114. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Operator time!
    map, filter, buffer
    87

    View Slide

  115. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    88
    Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  116. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    89

    View Slide

  117. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    90

    View Slide

  118. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    91

    View Slide

  119. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    92
    Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  120. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    93
    Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  121. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    94
    Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  122. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    95
    Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  123. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    96
    Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  124. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    97
    Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  125. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    98
    Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  126. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    99
    Flux.range(5, 3)
    .map(i -> i + 3)
    .filter(i -> i % 2 == 0)
    .buffer(3)

    View Slide

  127. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    100
    Flux.range(5, 3)
    .map(i -> i + 3)
    .filter(i -> i % 2 == 0)
    .buffer(3)
    5, 6, 7 |
    8, 9, 10 |
    8, 10 |
    [8,10]|

    View Slide

  128. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Operator time²!
    flatMap all the things
    101

    View Slide

  129. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Asynchronous sub-process
    ! Map to 0, 1 or N elements
    102
    flatMap operator

    View Slide

  130. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    103

    View Slide

  131. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    104

    View Slide

  132. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    105

    View Slide

  133. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    106
    flatMap(user -> tweetStream(user))

    View Slide

  134. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    107
    flatMap(user -> tweetStream(user))

    View Slide

  135. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    108
    flatMap(user -> tweetStream(user))

    View Slide

  136. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    109
    flatMap(user -> tweetStream(user))

    View Slide

  137. Unless otherwise indicated, these slides are 

    © 2013-2017 Pivotal Software, Inc. and licensed under a
    Creative Commons Attribution-NonCommercial
    license: http://creativecommons.org/licenses/by-nc/3.0/
    Coding Time!

    View Slide

  138. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Spring WebFlux

    View Slide

  139. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! It’s all about efficient resource usage
    ! Turn around the idea of imperative programming
    ! React to the availability of resources
    112
    What is Reactive Spring

    View Slide

  140. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Scaling
    113

    View Slide

  141. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Scaling
    113




    View Slide

  142. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Scaling
    113







    View Slide

  143. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Spring WebFlux – Reactive web applications
    ! Spring Data – Reactive data store support
    ! Spring Cloud Stream – Message-driven microservices
    ! Spring Boot – Reactive auto configuration
    ! Spring Security – Security for reactive web applications
    ! Spring Cloud Gateway – API Gateway
    114
    Reactive Spring portfolio

    View Slide

  144. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Spring’s reactive web framework
    ! End to end non-blocking and asynchronous execution
    115
    What is WebFlux?

    View Slide

  145. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Project Reactor 3.0
    ! Spring Framework 5.0
    ! Optional: Spring Boot 2.0
    116
    Requirements

    View Slide

  146. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    117

    View Slide

  147. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Servlet API is thread-bound
    ! Servlet API has no native HTTP/2 support (yet)
    ! No notion of back pressure
    ! SSE API’s (Server-sent events) are vendor-specific
    118
    Y U no Servlet API?

    View Slide

  148. Unless otherwise indicated, these slides are 

    © 2013-2017 Pivotal Software, Inc. and licensed under a
    Creative Commons Attribution-NonCommercial
    license: http://creativecommons.org/licenses/by-nc/3.0/
    Coding Time!

    View Slide

  149. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Allows usage of Reactive types
    ! Improves asynchronous usage (DeferredResult)
    ! Improves SSE streaming usage (ResponseBodyEmitter)
    ! Everything else is blocking
    120
    Spring Web MVC

    View Slide

  150. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Reactive Spring Data

    View Slide

  151. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Accessing data today
    122
    Request Data access
    Remote data
    service

    View Slide

  152. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Accessing data today
    122
    Request Data access
    Remote data
    service

    View Slide

  153. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Accessing data today
    122
    Request Data access
    Remote data
    service
    I/O Wait

    View Slide

  154. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Accessing data today
    122
    Request Data access
    Remote data
    service
    I/O Wait

    View Slide

  155. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Accessing data today
    122
    Request Data access
    Remote data
    service
    I/O Wait
    This one is
    waiting

    View Slide

  156. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Accessing data today
    122
    Request Data access
    Remote data
    service
    I/O Wait
    This one is
    waiting

    View Slide

  157. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Accessing data today
    123
    Request Data access
    Remote data
    service

    View Slide

  158. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Accessing data today
    123
    Request Data access
    Remote data
    service
    Bulk fetch

    View Slide

  159. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Accessing data today
    123
    Request Data access
    Remote data
    service
    Multiple
    calls
    Bulk fetch

    View Slide

  160. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Accessing data today
    123
    Request Data access
    Remote data
    service
    Multiple
    calls
    Bulk fetch

    View Slide

  161. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Accessing data today
    123
    Request Data access
    Remote data
    service
    Multiple
    calls
    Bulk fetch

    View Slide

  162. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Keep resources busy
    ! Connection contention
    ! Usually synchronous/blocking
    ! Multiple requests
    ! Asynchronous isn’t always a good answer
    124
    Todays’ data access

    View Slide

  163. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Project Reactor 3.0
    ! Spring Framework 5.0
    ! Spring Data 2.0
    ! A reactive (asynchronous, ideally non-blocking) driver
    ! Optional: Spring Boot 2.0
    125
    Requirements for Reactive Spring Data

    View Slide

  164. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Project Reactor 3.0
    ! Spring Framework 5.0
    ! Spring Data 2.0
    ! A reactive (asynchronous, ideally non-blocking) driver
    ! Optional: Spring Boot 2.0
    125
    Requirements for Reactive Spring Data

    View Slide

  165. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Reactive Template API
    ! Reactive Repository support
    ! Reduced feature set
    126
    Reactive Spring Data

    View Slide

  166. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! MongoDB
    ! Apache Cassandra
    ! Redis
    ! Couchbase
    127
    Reactive Spring Data modules

    View Slide

  167. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! JDBC is a blocking API
    ! JPA is a blocking API
    ! Sorry, no reactive JPA support so far
    128
    What about JPA

    View Slide

  168. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Not a priority but feasible
    • Neo4j
    • Solr
    • ElasticSearch
    129
    Future reactive Spring Data modules

    View Slide

  169. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Non-blocking I/O
    ! Threading-infrastructure
    ! Back pressure
    ! Integration with reactive libraries
    130
    Why reactive drivers?

    View Slide

  170. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Reactive fetch model
    131

    View Slide

  171. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Reactive fetch model
    131
    Data store
    App

    View Slide

  172. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Reactive fetch model
    131
    Data store
    App
    Data store

    View Slide

  173. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Reactive fetch model
    131
    Data store
    App
    Data store Data store

    View Slide

  174. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Reactive fetch model
    131
    Data store
    App
    Data store Data store Data store
    App

    View Slide

  175. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Reactive fetch model
    131
    Data store
    App
    Data store Data store Data store
    App

    View Slide

  176. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    132
    Imperative Template API
    T insert(T objectToSave)
    void insertAll(Collection<…> objects)

    View Slide

  177. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    133
    Reactive Template API
    Mono insert(T objectToSave)
    Mono insert(Mono objectToSave)

    View Slide

  178. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    134
    Reactive Repository API
    public interface ReactivePersonRepository extends
    ReactiveCrudRepository {


    Flux findByLastname(String lastname);


    @Query("{ 'firstname': ?0 }")

    Mono customQuery(String firstname);
    Flux findByLastname(Mono lastname);
    }

    View Slide

  179. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    135
    Reactive Repository API
    public interface ReactivePersonRepository extends
    ReactiveCrudRepository {


    Flux findByLastname(String lastname);


    @Query("{ 'firstname': ?0 }")

    Mono customQuery(String firstname);
    Flux findByLastname(Mono lastname);
    }

    View Slide

  180. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    136
    Reactive Repository API
    public interface ReactivePersonRepository extends
    ReactiveCrudRepository {


    Flux findByLastname(String lastname);


    @Query("{ 'firstname': ?0 }")

    Mono customQuery(String firstname);
    Flux findByLastname(Mono lastname);
    }

    View Slide

  181. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    137
    Reactive Repository API
    public interface ReactivePersonRepository extends
    ReactiveCrudRepository {


    Flux findByLastname(String lastname);


    @Query("{ 'firstname': ?0 }")

    Mono customQuery(String firstname);
    Flux findByLastname(Mono lastname);
    }

    View Slide

  182. Unless otherwise indicated, these slides are 

    © 2013-2017 Pivotal Software, Inc. and licensed under a
    Creative Commons Attribution-NonCommercial
    license: http://creativecommons.org/licenses/by-nc/3.0/
    Coding Time!

    View Slide

  183. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Blocking driver
    ! Reactive driver
    ! Requires both drivers and two connections
    ! Collection operations (CRUD, Geo-commands)
    ! Aggregation streaming
    ! No GridFS, MapReduce, Grouping support in Spring Data
    139
    Reactive MongoDB

    View Slide

  184. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Asynchronous driver (adoption layer)
    ! Feature parity
    ! Optional: Asynchronous Template API with ListenableFuture
    140
    Reactive Apache Cassandra

    View Slide

  185. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Reactive driver (used for blocking operations as well)
    ! Reactive Template API
    ! Planned: Reactive Pub/Sub
    ! No Reactive Repository support
    141
    Reactive Redis

    View Slide

  186. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Reactive driver (used for blocking operations as well)
    ! Reactive Template API
    ! Reactive Repository support
    142
    Reactive Couchbase

    View Slide

  187. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Going Reactive

    View Slide

  188. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Change your mindset
    ! Non-blocking
    • I/O
    • Computation
    ! Consider if reactive is benefit or burden
    144
    What does it take to go reactive?

    View Slide

  189. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Carefully consider whether it makes sense
    ! Functional-reactive programming is a good answer for a
    certain class of problems
    ! Can improve code
    ! Can clutter code
    145
    Existing applications

    View Slide

  190. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Get familiar with the vocabulary
    • Asynchronous
    • non-blocking
    • back pressure
    • reactive
    • reactive extensions
    • streams operators
    146
    Reactive language

    View Slide

  191. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Don’t implment Reactive Streams interfaces yourself
    • Unless you’re trying the RS TCK to pass
    ! Reactive Streams is just the contract
    • Use a reactive composition library
    ! Nothing happens until subscription
    147
    Reactive Streams

    View Slide

  192. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ! Carefully select your tools
    • API
    • Drivers
    ! Tooling is important
    ! Define code styles
    ! Learn reading the stack trace
    148
    Reactive composition library

    View Slide

  193. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    149

    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:644)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:579)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:496)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:458)
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
    at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory
    at java.lang.Thread.run(Thread.java:745)

    View Slide

  194. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    150
    java.lang.NullPointerException: The mapper returned a null value.
    at java.util.Objects.requireNonNull(Objects.java:228)
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java
    at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:37
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java
    at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:37
    at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:76)
    at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:37
    at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:
    at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:37
    at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:37
    at reactor.core.publisher.FluxFlatMap$FlatMapMain.innerNext(FluxFlatMap.java:778)

    View Slide

  195. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    151
    Assembly trace from producer [reactor.core.publisher.MonoMapFuseable] :
    reactor.core.publisher.Mono.map(Mono.java:2126)
    org.springframework.data.redis.core.DefaultReactiveValueOperations.lambda$get$12(DefaultRea
    org.springframework.data.redis.core.DefaultReactiveValueOperations.lambda$createMono$23(Def
    org.springframework.data.redis.core.ReactiveRedisTemplate.doInConnection(ReactiveRedisTempl
    org.springframework.data.redis.core.ReactiveRedisTemplate.lambda$createMono$1(ReactiveRedis
    reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:45)
    reactor.core.publisher.MonoSwitchIfEmpty.subscribe(MonoSwitchIfEmpty.java:44)
    reactor.core.publisher.Mono.block(Mono.java:1263)
    workshop.CachingController.getOrCreate(CachingController.java:44)
    org.springframework.web.reactive.result.method.InvocableHandlerMethod.doInvoke(InvocableHan
    org.springframework.web.reactive.result.method.InvocableHandlerMethod.lambda$invoke$0(Invoc

    View Slide

  196. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    152
    Error has been observed by the following operator(s):
    |_ Mono.map(DefaultReactiveValueOperations.java:157)
    |_ Flux.from(ReactiveRedisTemplate.java:296)
    |_ Flux.doOnSignal(ReactiveRedisTemplate.java:296)
    |_ Mono.from(ReactiveRedisTemplate.java:272)
    |_ Mono.defer(ReactiveRedisTemplate.java:272)
    |_ Mono.switchIfEmpty(CachingController.java:44)
    |_ Mono.error(InvocableHandlerMethod.java:127)
    |_ Mono.flatMap(InvocableHandlerMethod.java:116)
    |_ Mono.doOnSignal(RequestMappingHandlerAdapter.java:191)
    |_ Mono.error(RequestMappingHandlerAdapter.java:215)
    |_ Mono.onErrorResume(RequestMappingHandlerAdapter.java:192)
    |_ Mono.defer(RequestMappingHandlerAdapter.java:189)
    |_ Mono.then(RequestMappingHandlerAdapter.java:189)
    |_ Mono.flatMap(DispatcherHandler.java:129)
    |_ Mono.flatMap(DispatcherHandler.java:130)
    |_ Mono.error(ResponseStatusExceptionHandler.java:47)
    |_ Mono.onErrorResume(ExceptionHandlingWebHandler.java:67)

    View Slide

  197. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Questions?
    Mark Paluch • @mp911de

    View Slide

  198. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Resources
    ! Code - Repository @ Github
    ! Reactor Rx Lite API – Repository @ Github
    ! Spring Data Examples – Repository @ Github
    ! Spring projects release calendar – Google Calendar
    154
    @mp911de

    View Slide