$30 off During Our Annual Pro Sale. View Details »

projectreactor.io reactor3 intro

projectreactor.io reactor3 intro

Simon Baslé

April 04, 2017
Tweet

More Decks by Simon Baslé

Other Decks in Programming

Transcript

  1. View Slide

  2. the
    Agenda

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  6. WHY?
    because blocking is evil

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  11. Reactive Programming

    View Slide

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


    View Slide

  13. without sacrifice

    View Slide

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

    View Slide

  15. Pull? Push!

    View Slide

  16. Pull? Push!

    View Slide

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

    View Slide

  18. vs
    Iterable
    -
    Iterator
    Publisher
    -
    Subscriber

    View Slide

  19. Data in Flux

    View Slide

  20. Publisher Subscriber
    push events
    produces consumes
    feedback

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  24. Publisher Subscriber
    push events
    produces consumes
    feedback
    backpressure

    View Slide

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

    View Slide

  26. Publisher Subscriber
    push events
    produces consumes
    feedback

    View Slide

  27. Reactor 3
    types and operators

    View Slide

  28. Flux
    for 0..N elements

    View Slide

  29. View Slide

  30. Mono
    for at most 1 element

    View Slide

  31. View Slide

  32. Reactive Streams
    all the way

    View Slide

  33. focus on Java 8

    View Slide

  34. focus on Java 8
    Duration, CompletableFuture, Streams

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  41. examples

    View Slide

  42. Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  43. View Slide

  44. View Slide

  45. View Slide

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

    View Slide

  47. Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  48. Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  49. Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  50. Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  51. Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  52. Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

  53. Flux.range
    Subscriber
    map
    filter
    buffer

    View Slide

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

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

    View Slide

  56. View Slide

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

    View Slide

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

    View Slide

  59. go DEEPER!
    async sub-processes with flatMap

    View Slide

  60. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  65. View Slide

  66. & much
    more...

    View Slide

  67. threading
    contexts

    View Slide

  68. Reactor
    is
    agnostic

    View Slide

  69. however it
    facilitates switching

    View Slide

  70. Schedulers

    View Slide

  71. Schedulers
    elastic, parallel, single, timer...

    View Slide

  72. publishOn
    switch rest of the flux on a thread

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  80. Testing & Debugging
    in an asynchronous world

    View Slide

  81. Testing a Publisher
    StepVerifier

    View Slide

  82. Testing a Publisher
    with Virtual Time support

    View Slide

  83. Simulate a source
    TestPublisher

    View Slide

  84. Debugging Issues
    stacktraces get hard to decipher

    View Slide

  85. usually just show
    where Subscription happens

    View Slide

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

  87. Find where the Flux
    was instantiated (assembly)

    View Slide

  88. Checkpoint()
    or full assembly tracing

    View Slide

  89. costly!
    Checkpoint()
    or full assembly tracing

    View Slide

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

  91. BACKPRESSURE
    and other beasts

    View Slide

  92. Publisher Subscriber
    subscribe

    View Slide

  93. Publisher Subscriber
    push data as fast as possible

    View Slide

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

    View Slide

  95. Publisher Subscriber
    1 onNext

    View Slide

  96. Publisher Subscriber
    request more
    (eg. 2)

    View Slide

  97. Publisher Subscriber
    2 onNext

    View Slide

  98. Publisher Subscriber
    backpressure

    View Slide

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

    View Slide

  100. internal
    optimisations

    View Slide

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

    View Slide

  102. micro FUSION
    share internal structures for less allocation

    View Slide

  103. lock free operators

    View Slide

  104. lock free operators
    and Work Stealing
    cpu 1
    cpu 2
    cpu 3
    cpu 4
    cpu 5

    View Slide

  105. Reactor and
    Spring

    View Slide

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

    View Slide

  107. NO philosoraptor you don’t

    View Slide

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

    View Slide

  109. 5

    View Slide

  110. Java 8
    baseline

    View Slide

  111. reactive
    focus

    View Slide

  112. new WEB stack
    WebFlux

    View Slide

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

    View Slide

  114. functional option
    for Routing

    View Slide

  115. Spring Data
    reactive repositories

    View Slide

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

    View Slide

  117. Reactor and the Network
    reactor-netty

    View Slide

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

    View Slide

  119. Client / Server

    View Slide

  120. TCP
    or udp

    View Slide

  121. Http
    and WebSockets

    View Slide

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

  123. still a bit low level

    View Slide

  124. still a bit low level

    View Slide

  125. reactor-kafka
    topics as
    Flux

    View Slide

  126. reactive API
    over Kafka Producer / Consumer

    View Slide

  127. send(Flux)
    into Kafka

    View Slide

  128. Flux receive()
    from Kafka

    View Slide

  129. (currently in MILESTONE 1)

    View Slide

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