Reactor 3

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)

Fda20bf9d9c85c4390ca7237beba45a2?s=128

Simon Baslé

February 22, 2017
Tweet

Transcript

  1. Reactor 3 a Reactive foundation for the JVM

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

  3. First a Survey

  4. Who Here Uses...

  5. Who Here Uses... Java 8

  6. Who Here Uses... Java 8 RxJava

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

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

  9. ok bad joke, done

  10. the Agenda

  11. None
  12. 101 Reactive Programming

  13. 101 Reactive Programming types & operators Reactor 3

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

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

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

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

    Reactor debugging testing and reactor-netty other beasts backpressure and reactor-kafka...
  18. Reactive Programming 101 what does it bring to the table?

  19. WHY?

  20. WHY? because blocking is evil

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

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

    nothing
  23. async & blocking main thread wait & join ! new

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

    threads, costly ! complex BAD
  25. async & nonblocking “event loop” in non-blocking processing chunks no

    more threads than needed
  26. how do you achieve that without losing your mind ?

  27. Reactive Programming

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

  29. without sacrifice

  30. without sacrifice Callbacks ? Futures ? easy to block hard

    to compose callback hell ! not readable
  31. Pull? Push!

  32. Pull? Push!

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

  34. vs Iterable - Iterator Publisher - Subscriber

  35. Data in Flux

  36. Publisher Subscriber push events produces consumes feedback

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

    events produces
  38. Publisher Subscriber push events produces consumes feedback Subscriber<T> onNext(T) onComplete();

    onError(Throwable);
  39. Publisher Subscriber produces consumes feedback 0..N elements + 0..1 (complete

    | error)
  40. Publisher Subscriber push events produces consumes feedback backpressure

  41. Publisher Subscriber push events produces consumes feedback can I have

    an API though?
  42. Publisher Subscriber push events produces consumes feedback

  43. Reactor 3 types and operators

  44. Flux<T> for 0..N elements

  45. None
  46. Mono<T> for at most 1 element

  47. None
  48. Reactive Streams all the way

  49. focus on Java 8

  50. focus on Java 8 Duration, CompletableFuture, Streams

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

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

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

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

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

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

    Sub
  57. examples

  58. Flux.range Subscriber map filter buffer

  59. None
  60. None
  61. None
  62. Flux.range Subscriber map filter buffer

  63. Flux.range Subscriber map filter buffer

  64. Flux.range Subscriber map filter buffer

  65. Flux.range Subscriber map filter buffer

  66. Flux.range Subscriber map filter buffer

  67. Flux.range Subscriber map filter buffer

  68. Flux.range Subscriber map filter buffer

  69. Flux.range(5, 3) .map(i -> i + 3) .filter(i -> i

    % 2 == 0) .buffer(3)
  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]|
  71. Flux.from Subscriber map filter retry Publisher from HTTP reactive client

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

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

    resubscribe
  75. go DEEPER! async sub-processes with flatMap

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

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

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

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

  81. None
  82. & much more...

  83. threading contexts

  84. Reactor is agnostic

  85. however it facilitates switching

  86. Schedulers

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

  88. publishOn switch rest of the flux on a thread

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

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

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

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

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

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

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

    Sub Sub Sub Sub Sub Sub
  96. Testing & Debugging in an asynchronous world

  97. Testing a Publisher StepVerifier

  98. Testing a Publisher with Virtual Time support

  99. Simulate a source TestPublisher

  100. Debugging Issues stacktraces get hard to decipher

  101. usually just show where Subscription happens

  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)
  103. Find where the Flux was instantiated (assembly)

  104. Checkpoint() or full assembly tracing

  105. costly! Checkpoint() or full assembly tracing

  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)

  107. BACKPRESSURE and other beasts

  108. Publisher Subscriber subscribe

  109. Publisher Subscriber push data as fast as possible

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

  111. Publisher Subscriber 1 onNext

  112. Publisher Subscriber request more (eg. 2)

  113. Publisher Subscriber 2 onNext

  114. Publisher Subscriber backpressure

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

  116. internal optimisations

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

  118. micro FUSION share internal structures for less allocation

  119. lock free operators

  120. lock free operators and Work Stealing CPU 1 CPU 2

    CPU 3 CPU 4 CPU 5
  121. Reactor and Spring

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

    Reactor ?
  123. NO philosoraptor you don’t

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

    other way around
  125. 5

  126. Java 8 baseline

  127. reactive focus

  128. new WEB stack WebFlux

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

    }
  130. functional option for Routing

  131. Spring Data reactive repositories

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

  133. Reactor and the Network reactor-netty

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

  135. Client / Server

  136. TCP or udp

  137. Http and WebSockets

  138. HttpServer.create(0) .newHandler((in, out) -> out .sendWebsocket((i, o) -> o.options(opt ->

    opt.flushOnEach()) .sendString(Flux.just("test") .delayElementsMillis(100) .repeat()) ) ) .block();
  139. still a bit low level

  140. still a bit low level

  141. reactor-kafka topics as Flux<T>

  142. reactive API over Kafka Producer / Consumer

  143. send(Flux) into Kafka

  144. Flux receive() from Kafka

  145. (currently in MILESTONE 2)

  146. Questions?

  147. Thanks!

  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.