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

Reactor 3

Simon Baslé
February 22, 2017

Reactor 3

Reactor 3, a reactive foundation for the JVM

Introduction to reactive programming, Reactor 3 and a bit of Spring 5.

(note: presentation will be re-uploaded if it is updated, so it might not 100% correspond to the version I used at talks in the past)

Simon Baslé

February 22, 2017
Tweet

More Decks by Simon Baslé

Other Decks in Programming

Transcript

  1. Reactor 3
    a Reactive foundation for
    the JVM

    View Slide

  2. About me
    &
    how to get in touch
    @SimonBasle

    View Slide

  3. First
    a
    Survey

    View Slide

  4. Who Here Uses...

    View Slide

  5. Who Here Uses...
    Java 8

    View Slide

  6. Who Here Uses...
    Java 8
    RxJava

    View Slide

  7. Who Here Uses...
    Java 8
    RxJava
    Reactive Streams

    View Slide

  8. Who Here Thinks...
    Reactor is a fork of Atom editor

    View Slide

  9. ok bad joke, done

    View Slide

  10. the
    Agenda

    View Slide

  11. View Slide

  12. 101
    Reactive
    Programming

    View Slide

  13. 101
    Reactive
    Programming
    types &
    operators
    Reactor 3

    View Slide

  14. 101
    Reactive
    Programming
    types &
    operators
    Reactor 3
    other beasts
    backpressure
    and

    View Slide

  15. 101
    Reactive
    Programming
    types &
    operators
    Reactor 3
    debugging
    testing
    and
    other beasts
    backpressure
    and

    View Slide

  16. 101
    Reactive
    Programming
    types &
    operators
    Reactor 3
    and Spring
    Reactor
    debugging
    testing
    and
    other beasts
    backpressure
    and

    View Slide

  17. 101
    Reactive
    Programming
    types &
    operators
    Reactor 3
    and Spring
    Reactor
    debugging
    testing
    and
    reactor-netty
    other beasts
    backpressure
    and
    reactor-kafka...

    View Slide

  18. Reactive Programming 101
    what does it bring to the table?

    View Slide

  19. WHY?

    View Slide

  20. WHY?
    because blocking is evil

    View Slide

  21. sync/blocking
    main thread processing
    resumes
    I/O
    ! app does
    nothing

    View Slide

  22. sync/blocking
    main thread processing
    resumes
    I/O
    BAD
    ! app does
    nothing

    View Slide

  23. async & blocking
    main thread wait &
    join
    ! new
    threads,
    costly
    ! complex

    View Slide

  24. async & blocking
    main thread wait &
    join
    ! new
    threads,
    costly
    ! complex
    BAD

    View Slide

  25. async & nonblocking
    “event loop”
    in non-blocking
    processing
    chunks
    no more threads
    than needed

    View Slide

  26. how do you achieve that
    without losing your mind ?

    View Slide

  27. Reactive Programming

    View Slide

  28. Composing asynchronous
    & event-based sequences,
    using non-blocking operators


    View Slide

  29. without sacrifice

    View Slide

  30. without sacrifice
    Callbacks ?
    Futures ?
    easy to block
    hard to compose
    callback hell !
    not readable

    View Slide

  31. Pull? Push!

    View Slide

  32. Pull? Push!

    View Slide

  33. Pull? Push!
    (or actually a little bit of Both)

    View Slide

  34. vs
    Iterable
    -
    Iterator
    Publisher
    -
    Subscriber

    View Slide

  35. Data in Flux

    View Slide

  36. Publisher Subscriber
    push events
    produces consumes
    feedback

    View Slide

  37. interfaces from
    Reactive Streams
    spec
    Publisher Subscriber
    feedback
    consumes
    push events
    produces

    View Slide

  38. Publisher Subscriber
    push events
    produces consumes
    feedback
    Subscriber
    onNext(T)
    onComplete();
    onError(Throwable);

    View Slide

  39. Publisher Subscriber
    produces consumes
    feedback
    0..N elements
    +
    0..1 (complete | error)

    View Slide

  40. Publisher Subscriber
    push events
    produces consumes
    feedback
    backpressure

    View Slide

  41. Publisher Subscriber
    push events
    produces consumes
    feedback
    can I have an
    API though?

    View Slide

  42. Publisher Subscriber
    push events
    produces consumes
    feedback

    View Slide

  43. Reactor 3
    types and operators

    View Slide

  44. Flux
    for 0..N elements

    View Slide

  45. View Slide

  46. Mono
    for at most 1 element

    View Slide

  47. View Slide

  48. Reactive Streams
    all the way

    View Slide

  49. focus on Java 8

    View Slide

  50. focus on Java 8
    Duration, CompletableFuture, Streams

    View Slide

  51. an Rx-inspired API
    with a vocabulary of operators similar to RxJava...

    View Slide

  52. an Rx-inspired API
    ...but not exactly the same

    View Slide

  53. Flux/Mono
    generator
    operator
    operator
    operator
    nothing
    happens
    until you
    subscribe

    View Slide

  54. Flux/Mono
    generator
    Subscriber
    operator
    operator
    operator
    nothing
    happens
    until you
    subscribe

    View Slide

  55. Flux/Mono
    generator
    Subscriber
    operator
    operator
    operator
    per
    Subscription
    state
    Sub
    Sub
    Sub

    View Slide

  56. Flux/Mono
    generator
    Subscriber
    operator
    operator
    operator
    data
    flows
    Sub
    Sub
    Sub

    View Slide

  57. examples

    View Slide

  58. Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  59. View Slide

  60. View Slide

  61. View Slide

  62. Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  63. Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  64. Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  65. Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  66. Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  67. Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  68. Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  69. Flux.range(5, 3)
    .map(i -> i + 3)
    .filter(i -> i % 2 == 0)
    .buffer(3)

    View Slide

  70. 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

  71. Flux.from
    Subscriber
    map
    filter
    retry
    Publisher from
    HTTP reactive
    client

    View Slide

  72. View Slide

  73. Flux.from
    Subscriber
    map
    filter
    retry
    Publisher from
    HTTP reactive
    client

    View Slide

  74. Flux.from
    Subscriber
    map
    filter
    retry
    Publisher from
    HTTP reactive
    client
    resubscribe

    View Slide

  75. go DEEPER!
    async sub-processes with flatMap

    View Slide

  76. View Slide

  77. flatMap(user -> tweetStream(user))

    View Slide

  78. flatMap(user -> tweetStream(user))

    View Slide

  79. flatMap(user -> tweetStream(user))

    View Slide

  80. flatMap(user -> tweetStream(user))

    View Slide

  81. View Slide

  82. & much
    more...

    View Slide

  83. threading
    contexts

    View Slide

  84. Reactor
    is
    agnostic

    View Slide

  85. however it
    facilitates switching

    View Slide

  86. Schedulers

    View Slide

  87. Schedulers
    elastic, parallel, single, timer...

    View Slide

  88. publishOn
    switch rest of the flux on a thread

    View Slide

  89. subscribeOn
    make the subscription and request happen
    on a particular thread

    View Slide

  90. Flux/Mono
    generator
    operator
    subscribeO
    n
    operator
    publishOn
    operator
    operator
    Subscriber
    Sub
    Sub
    Sub
    Sub
    Sub
    Sub

    View Slide

  91. Flux/Mono
    generator
    operator
    subscribe
    On
    operator
    publish
    On
    operator
    operator
    Subscriber
    Sub
    Sub
    Sub
    Sub
    Sub
    Sub

    View Slide

  92. Flux/Mono
    generator
    operator
    subscribeO
    n
    operator
    publishOn
    operator
    operator
    Subscriber
    Sub
    Sub
    Sub
    Sub
    Sub
    Sub

    View Slide

  93. Flux/Mono
    generator
    operator
    subscribeO
    n
    operator
    publishOn
    operator
    operator
    Subscriber
    Sub
    Sub
    Sub
    Sub
    Sub
    Sub

    View Slide

  94. Flux/Mono
    generator
    operator
    subscribeO
    n
    operator
    publishOn
    operator
    operator
    Subscriber
    Sub
    Sub
    Sub
    Sub
    Sub
    Sub

    View Slide

  95. Flux/Mono
    generator
    operator
    subscribeO
    n
    operator
    publishOn
    operator
    operator
    Subscriber
    Sub
    Sub
    Sub
    Sub
    Sub
    Sub

    View Slide

  96. Testing & Debugging
    in an asynchronous world

    View Slide

  97. Testing a Publisher
    StepVerifier

    View Slide

  98. Testing a Publisher
    with Virtual Time support

    View Slide

  99. Simulate a source
    TestPublisher

    View Slide

  100. Debugging Issues
    stacktraces get hard to decipher

    View Slide

  101. usually just show
    where Subscription happens

    View Slide

  102. java.lang.IndexOutOfBoundsException: Source emitted more than one item
    at reactor.core.publisher.MonoSingle$SingleSubscriber.onNext(MonoSingle.java:120)
    at
    reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:314)
    ...
    ...
    at reactor.core.publisher.Mono.subscribeWith(Mono.java:2668)
    at reactor.core.publisher.Mono.subscribe(Mono.java:2629)
    at reactor.core.publisher.Mono.subscribe(Mono.java:2604)
    at reactor.core.publisher.Mono.subscribe(Mono.java:2582)
    at reactor.guide.GuideTests.debuggingActivated(GuideTests.java:727)

    View Slide

  103. Find where the Flux
    was instantiated (assembly)

    View Slide

  104. Checkpoint()
    or full assembly tracing

    View Slide

  105. costly!
    Checkpoint()
    or full assembly tracing

    View Slide

  106. Assembly trace from producer [reactor.core.publisher.MonoSingle] :
    reactor.core.publisher.Flux.single(Flux.java:5335)
    reactor.guide.GuideTests.scatterAndGather(GuideTests.java:689)
    reactor.guide.GuideTests.populateDebug(GuideTests.java:702)

    View Slide

  107. BACKPRESSURE
    and other beasts

    View Slide

  108. Publisher Subscriber
    subscribe

    View Slide

  109. Publisher Subscriber
    push data as fast as possible

    View Slide

  110. Publisher Subscriber
    subscribe
    with small request
    (eg. 1)

    View Slide

  111. Publisher Subscriber
    1 onNext

    View Slide

  112. Publisher Subscriber
    request more
    (eg. 2)

    View Slide

  113. Publisher Subscriber
    2 onNext

    View Slide

  114. Publisher Subscriber
    backpressure

    View Slide

  115. other ways of dealing with backpressure
    eg. drop, buffer...

    View Slide

  116. internal
    optimisations

    View Slide

  117. macro FUSION
    avoids unnecessary request back-and-forth

    View Slide

  118. micro FUSION
    share internal structures for less allocation

    View Slide

  119. lock free operators

    View Slide

  120. lock free operators
    and Work Stealing
    CPU 1
    CPU 2
    CPU 3
    CPU 4
    CPU 5

    View Slide

  121. Reactor and
    Spring

    View Slide

  122. Reactor and
    Spring
    and do I need Spring to use Reactor ?

    View Slide

  123. NO philosoraptor you don’t

    View Slide

  124. Reactor 3
    is a dependency of
    Spring 5
    not the other way around

    View Slide

  125. 5

    View Slide

  126. Java 8
    baseline

    View Slide

  127. reactive
    focus

    View Slide

  128. new WEB stack
    WebFlux

    View Slide

  129. @RestController(“/user”)
    public class UserController {
    @GetMapping(“/{id}”)
    Mono getUser(String id) {...}
    }

    View Slide

  130. functional option
    for Routing

    View Slide

  131. Spring Data
    reactive repositories

    View Slide

  132. @GetMapping(“/{id}”)
    Mono getUser(String id) {
    return reactiveRepo.findOne(id);
    }

    View Slide

  133. Reactor and the Network
    reactor-netty

    View Slide

  134. reactor-netty
    builds on Netty to provide
    reactive I/O

    View Slide

  135. Client / Server

    View Slide

  136. TCP
    or udp

    View Slide

  137. Http
    and WebSockets

    View Slide

  138. HttpServer.create(0)
    .newHandler((in, out) -> out
    .sendWebsocket((i, o) ->
    o.options(opt -> opt.flushOnEach())
    .sendString(Flux.just("test")
    .delayElementsMillis(100)
    .repeat())
    )
    )
    .block();

    View Slide

  139. still a bit low level

    View Slide

  140. still a bit low level

    View Slide

  141. reactor-kafka
    topics as
    Flux

    View Slide

  142. reactive API
    over Kafka Producer / Consumer

    View Slide

  143. send(Flux)
    into Kafka

    View Slide

  144. Flux receive()
    from Kafka

    View Slide

  145. (currently in MILESTONE 2)

    View Slide

  146. Questions?

    View Slide

  147. Thanks!

    View Slide

  148. Credits
    ● Springfield Plant: copyright FOX
    ● Raised Hand: CC0 (via Pixabay)
    ● Checklist: CC-By Crispy (via Flickr)
    ● Robot Devil: copyright FOX
    ● Volume Knob: CC0 (via Pixabay)
    ● Camel Shape: CC0 (via Pixabay)
    ● Dromedary Shape: CC-By-SA USPN,Whidou (via Wikimedia)
    ● Dam: CC-By-SA Matthew Hatton (via geograph.org.uk)
    ● Cogs: CC0 (via publicdomainpictures.net)
    ● Thread Balls: CC0 (via Pixabay)
    ● The Fortune Teller: Georges de la Tour (public domain)
    ● Microphone: CC0 (via Pexels)
    ● End Sands: CC0 (via Pixabay)
    ● logos: Pivotal, Spring, Twitter and Github logo copyright their
    respective companies.

    View Slide