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

Introduction to Reactor & Reactive Streams

Introduction to Reactor & Reactive Streams

Stephane Maldini

December 02, 2014
Tweet

More Decks by Stephane Maldini

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/ Reactor and Reactive Streams
 for MicroServices Stephane Maldini, Solutions Architect, Pivotal @smaldini
  2. 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/ 2 @smaldini - solve 9 issues, create 10 problems Customer Success Organization @ Pivotal Reactor Committer II Try to contribute to Reactive-Streams
  3. 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/ NanoService, MicroService, NotTooBigService™… cat file.csv 3
  4. 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/ NanoService, MicroService, NotTooBigService™… cat file.csv 3 | grep ‘doge’
  5. 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/ NanoService, MicroService, NotTooBigService™… cat file.csv 3 | sort | grep ‘doge’
  6. 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/ NanoService, MicroService, NotTooBigService™… POST [json] http://dogecoin.money/send/ 4
  7. 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/ NanoService, MicroService, NotTooBigService™… POST [json] http://dogecoin.money/send/ 4 —> GET [json] http://dogeprofile.money/id
  8. 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/ NanoService, MicroService, NotTooBigService™… POST [json] http://dogecoin.money/send/ 4 —> GET [json] http://dogeprofile.money/id —> POST [json] http://nsa.gov.us/cc/trace/id
  9. 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/ NanoService, MicroService, NotTooBigService™… § A SomethingService will always need to interact • With the user • With other services § The boundary between services is the real deal • A boundary is a separation in time and space 5
  10. 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/ Dealing with reality: Latency 6
  11. 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/ Latency 7 UberFact : Humans don’t really enjoy waiting
  12. 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/ Neither do The Machines 8 http://ferd.ca/queues-don-t-fix-overload.html
  13. 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/ What is latency doing to you ? § Loss of revenues • because users switched to another site/app • because services are compounding inefficiency • because aggressive scaling will be needed 9
  14. 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/ 10 Loading
  15. 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/ 10 Loading
  16. 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/ All hail Reactive Programming § A possible answer to this issue § The very nature of Reactor, look at the name dude § A fancy buzz-word that might work better than MDA or SOA § A simple accumulation of years of engineering 11
  17. 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/ Seriously, what is Reactive Programming ? 12
  18. 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/ Seriously, what is Reactive Programming ? 12 Event-Driven
  19. 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/ Seriously, what is Reactive Programming ? 12 Fault-Tolerant Event-Driven
  20. 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/ Seriously, what is Reactive Programming ? 12 Fault-Tolerant Event-Driven Elastic
  21. 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/ Seriously, what is Reactive Programming ? 12 Low-latency* Fault-Tolerant Event-Driven Elastic
  22. 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 Architecture ? § A Reactive system MUST be resilient • splitting concerns to achieve error bulk-heading and modularity § A Reactive system MUST be scalable • scale-up : partition work across CPUs • scale-out : distribute over peer nodes 13
  23. 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/ Reactor has 99 problems but Latency isn’t one 14
  24. 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/ Reactor-Core features 15
  25. 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/ Reactor-Core features 15 [A]synchronous Dispatchers
  26. 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/ Reactor-Core features 15 Event Bus [A]synchronous Dispatchers
  27. 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/ Reactor-Core features 15 Event Bus [A]synchronous Dispatchers Streams and Promises
  28. 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/ Reactor-Core features 15 Functional artifacts (SAM components, tuples, timers) Event Bus [A]synchronous Dispatchers Streams and Promises
  29. 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/ Reactor-Core features 15 Functional artifacts (SAM components, tuples, timers) Event Bus [A]synchronous Dispatchers Streams and Promises Fast IO [buffer, net, persistent queues, codec]
  30. 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/ Reactor-Core features 15 Functional artifacts (SAM components, tuples, timers) Event Bus [A]synchronous Dispatchers Streams and Promises Fast IO [buffer, net, persistent queues, codec] Fast Data [allocators, batch- processors]
  31. import reactor.rx.spec.Streams def stream = Streams.defer() stream.map{ name -> Tuple.of(name,

    'so wow') }.map{ tuple -> Tuple.of(tuple.t1, "$tuple.t2, much sad") }.consume{ tuple -> println "bye bye ! $tuple.t2... $tuple.t1" } stream.broadcastNext('Doge') 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/ Using a Stream ? 16
  32. import reactor.rx.spec.Streams def stream = Streams.defer() stream.map{ name -> Tuple.of(name,

    'so wow') }.map{ tuple -> Tuple.of(tuple.t1, "$tuple.t2, much sad") }.consume{ tuple -> println "bye bye ! $tuple.t2... $tuple.t1" } stream.broadcastNext('Doge') 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/ Prepare a simple Stream Using a Stream ? 16
  33. import reactor.rx.spec.Streams def stream = Streams.defer() stream.map{ name -> Tuple.of(name,

    'so wow') }.map{ tuple -> Tuple.of(tuple.t1, "$tuple.t2, much sad") }.consume{ tuple -> println "bye bye ! $tuple.t2... $tuple.t1" } stream.broadcastNext('Doge') 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/ Prepare a simple Stream 1st step Using a Stream ? 16
  34. import reactor.rx.spec.Streams def stream = Streams.defer() stream.map{ name -> Tuple.of(name,

    'so wow') }.map{ tuple -> Tuple.of(tuple.t1, "$tuple.t2, much sad") }.consume{ tuple -> println "bye bye ! $tuple.t2... $tuple.t1" } stream.broadcastNext('Doge') 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/ Prepare a simple Stream 1st step 2nd step Using a Stream ? 16
  35. import reactor.rx.spec.Streams def stream = Streams.defer() stream.map{ name -> Tuple.of(name,

    'so wow') }.map{ tuple -> Tuple.of(tuple.t1, "$tuple.t2, much sad") }.consume{ tuple -> println "bye bye ! $tuple.t2... $tuple.t1" } stream.broadcastNext('Doge') 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/ Prepare a simple Stream 1st step 2nd step Terminal callback Using a Stream ? 16
  36. import reactor.rx.spec.Streams def stream = Streams.defer() stream.map{ name -> Tuple.of(name,

    'so wow') }.map{ tuple -> Tuple.of(tuple.t1, "$tuple.t2, much sad") }.consume{ tuple -> println "bye bye ! $tuple.t2... $tuple.t1" } stream.broadcastNext('Doge') 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/ Prepare a simple Stream 1st step 2nd step Terminal callback Send some data into the stream Using a Stream ? 16
  37. 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/ Using a Stream ? 17 Embedded data-processing Event Processing Metrics, Statistics Micro-Batching Composition Error Handling
  38. 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/ Stream Oriented Services § [CODE] 18 Win this way class UserService{ User authenticateUser(long id) throws Exception{ User.findById(id) }
  39. 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/ Stream Oriented Services § [CODE] 18 Win this way class UserService{ User authenticateUser(long id) throws Exception{ User.findById(id) } class UserService{ Stream<User> authenticateUser(long id){ Streams.create{ it.onNext(User.findById(id)) it.oncComplete() } } }
  40. 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/ Defining a Stream § Represents a sequence of data, possibly unbounded § Provide for processing API such as filtering and enrichment § Not a Collection, not a Storage 19
  41. 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/ Stream VS Event Bus [Reactor] § Works great combined (stream distribution) § Type-checked flow § Publisher/Subscriber tight control § No Signal concurrency 20
  42. 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/ Stream VS Event Bus [Reactor] § Works great combined (stream distribution) § Type-checked flow § Publisher/Subscriber tight control § No Signal concurrency 20 Rule of thumb: if nested event composition > 2, switch to Stream
  43. 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/ Hot Stream vs Cold Stream § An Hot Stream multi-casts real-time signals • think Trade, Tick, Mouse Click, Websocket § A Cold Stream uni-casts deferred signals • think File, Array, Computation result (Future) 21
  44. 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/ Reactor : Iterable Cold Stream 22 Streams .just(1, 2, 3, 4, 5) .take(3) .consume(System.out::println);
  45. LapinStreams .fromQueue(queueName) .dispatchOn(Environment.get()) .timeout(30) .consume(System.out::println); 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/ Reactor : AMQP Hot Stream 23
  46. LapinStreams .fromQueue(queueName) .dispatchOn(Environment.get()) .timeout(30) .consume(System.out::println); 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/ Reactor : AMQP Hot Stream 23 COMING SOON IN A REPOSITORY NEAR YOU
  47. 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/ Introducing Reactive Streams Specification ! 24
  48. 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/ What is defined by Reactive Streams ? 25
  49. 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/ What is defined by Reactive Streams ? 25 Async non-blocking data sequence
  50. 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/ What is defined by Reactive Streams ? 25 Async non-blocking data sequence Minimal resources requirement
  51. 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/ What is defined by Reactive Streams ? 25 Interoperable protocol 
 (Threads, Nodes…) Async non-blocking data sequence Minimal resources requirement
  52. 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/ What is defined by Reactive Streams ? 25 Async non-blocking flow-control Interoperable protocol 
 (Threads, Nodes…) Async non-blocking data sequence Minimal resources requirement
  53. 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-Streams: Dynamic Message-Passing 26
  54. 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-Streams: Dynamic Message-Passing 26 PUBLISHER
  55. 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-Streams: Dynamic Message-Passing 26 PUBLISHER SUBSCRIBER
  56. 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-Streams: Dynamic Message-Passing 26 PUBLISHER SUBSCRIBER
  57. 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-Streams: Dynamic Message-Passing 26 PUBLISHER SUBSCRIBER Events
  58. 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-Streams: Dynamic Message-Passing 26 PUBLISHER SUBSCRIBER Events Demand
  59. 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/ Now You Know § It is not only queue-based pattern: • Signaling demand on a slower Publisher == no buffering • Signaling demand on a faster Publisher == buffering § Data volume is bounded by a Subscriber • Scaling dynamically if required 27
  60. 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/ Out Of The Box : Flow Control 28
  61. 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/ Out Of The Box : Flow Control 28 PUBLISHER
  62. 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/ Out Of The Box : Flow Control 28 PUBLISHER SUBSCRIBER
  63. 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/ Out Of The Box : Flow Control 28 PUBLISHER SUBSCRIBER
  64. 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/ Out Of The Box : Flow Control 28 PUBLISHER SUBSCRIBER Slow SUBSCRIBER
  65. 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/ Out Of The Box : Flow Control 28 PUBLISHER SUBSCRIBER Slow SUBSCRIBER
  66. 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/ Out Of The Box : Flow Control 28 PUBLISHER SUBSCRIBER Slow SUBSCRIBER
  67. 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/ Out Of The Box : Flow Control 28 PUBLISHER SUBSCRIBER Slow SUBSCRIBER Fast
  68. 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 Streams: Signals 29 onError | (onSubscribe onNext* (onError | onComplete)?)
  69. 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/ ccv Doug Lea – SUNY Oswego Reactive Streams: Joining forces 30
  70. 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/ Reactor Data Driver Akka Distributed System RxJava Metrics Pipeline Ratpack HTTP server Reactive Streams: Joining forces 31
  71. 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/ Reactor Data Driver Akka Distributed System RxJava Metrics Pipeline Ratpack HTTP server Reactive Streams: Joining forces 31
  72. 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/ Reactor Data Driver Akka Distributed System RxJava Metrics Pipeline Ratpack HTTP server Reactive Streams: Joining forces 31
  73. 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/ Reactor Data Driver Akka Distributed System RxJava Metrics Pipeline Ratpack HTTP server Reactive Streams: Joining forces 31
  74. 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/ Reactor Data Driver Akka Distributed System RxJava Metrics Pipeline Ratpack HTTP server Reactive Streams: Joining forces 31
  75. 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/ Reactor Data Driver Akka Distributed System RxJava Metrics Pipeline Ratpack HTTP server Reactive Streams: Joining forces 31
  76. 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/ Reactor Data Driver Akka Distributed System RxJava Metrics Pipeline Ratpack HTTP server Reactive Streams: Joining forces 31
  77. 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 Streams: An industrial matured spec § Semantics • Single document listing full rules • Open enough to allow for various patterns § 4 API Interfaces • Publisher, Subscriber, Subscription, Processor § TCK to verify implementation behavior 32
  78. 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 Streams: org.reactivestreams 33 public interface Publisher<T> { public void subscribe(Subscriber<T> s); } public interface Subscriber<T> { public void onSubscribe(Subscription s); public void onNext(T t); public void onError(Throwable t); public void onComplete(); } public interface Subscription { public void request(int n); public void cancel(); }
  79. 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 Streams: org.reactivestreams 33 public interface Publisher<T> { public void subscribe(Subscriber<T> s); } public interface Subscriber<T> { public void onSubscribe(Subscription s); public void onNext(T t); public void onError(Throwable t); public void onComplete(); } public interface Subscription { public void request(int n); public void cancel(); } public interface Processor<T, R> extends Subscriber<T>, Publisher<R> {}
  80. 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/ Reactor <=> Reactive Streams 34 Publisher reactor.rx.Stream Subscriber reactor.rx.actions.Action Processor reactor.rx.Promise
  81. 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/ Reactor <=> Reactive Streams 34 Publisher reactor.rx.Stream Subscriber reactor.rx.actions.Action Processor reactor.rx.Promise
  82. 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/ Reactor <=> Reactive Streams 34 Publisher reactor.rx.Stream Subscriber reactor.rx.actions.Action Processor reactor.rx.Promise
  83. 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/ Reactor <=> Reactive Streams 34 Publisher reactor.rx.Stream Subscriber reactor.rx.actions.Action Processor reactor.rx.Promise
  84. 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/ Reactor <=> Reactive Streams 34 Publisher reactor.rx.Stream Subscriber reactor.rx.actions.Action Processor reactor.rx.Promise
  85. 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/ Reactor <=> Reactive Streams 34 Publisher reactor.rx.Stream Subscriber reactor.rx.actions.Action Processor reactor.rx.Promise
  86. 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/ 35
  87. 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/ 35 What about RxJava mate ! All those hipsters use it.
  88. 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/ Reactor == RxJava § Reactor Streams 2.0 are inspired by Rx and RxJava • http://msdn.microsoft.com/en-gb/data/gg577609.aspx • Naming and behavior is mostly aligned with RxJava (just, flatMap, retry…) • Rx Patterns should apply to Reactor Streams • Lightweight, embeddable 36
  89. 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/ Reactor != RxJava § Reactor Streams mission: • Data throughput over Functional facilities (Dispatchers, Subscription model, pre-allocation) • Pivotal integration (Spring.io, RabbitMQ, Redis, CloudFoundry, Gemfire…) • Native Reactive Streams, all Stream actions benefit from back pressure model and can talk to any implementation 37
  90. 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/ slidesSubscription.request(18); //talkSubscription.cancel(); 38
  91. 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/ 39
  92. 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/ 39 Let’s finish with practical patterns to empower your Reactive Service
  93. 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 Streams: Async Boundaries 40 httpRequestStream map(f) filter(p) consume(httpResponseConsumer) Resource #1 Resource #4 R2 R3 dispatchOn(dispatcher4) dispatchOn(dispatcher1) disp[..] disp[..]
  94. 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 Streams: Async Boundaries 40 httpRequestStream map(f) filter(p) consume(httpResponseConsumer) Resource #1 Resource #4 R2 R3 dispatchOn(dispatcher4) Not that efficient dispatchOn(dispatcher1) disp[..] disp[..]
  95. 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 Streams: Async Boundaries 41 httpRequestStream map(f) filter(p) consume(httpResponseConsumer) Resource #1 Resource #4 dispatchOn(dispatcher14) dispatchOn(dispatcher1)
  96. 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 Streams: Async Boundaries 41 httpRequestStream map(f) filter(p) consume(httpResponseConsumer) Resource #1 Resource #4 dispatchOn(dispatcher14) Non Blocking Stream until last callback dispatchOn(dispatcher1)
  97. 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 Streams: Async Boundaries 42 httpRequestStream map(f) filter(p) consume(httpResponseConsumer) Resource #1 Resource #2 dispatchOn(dispatcher1) dispatchOn(dispatcher2)
  98. 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 Streams: Async Boundaries 42 httpRequestStream map(f) filter(p) consume(httpResponseConsumer) Resource #1 Resource #2 81,2% OK, producer not blocked dispatchOn(dispatcher1) dispatchOn(dispatcher2)
  99. 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/ A Full Slide Just To Talk About flatMap() 43
  100. 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/ A Full Slide Just To Talk About flatMap() 43 FlatMap Bucket Challenge ! Nominate 3 friends to explain flatMap()
  101. 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/ Another Slide Just To Talk About flatMap() 44
  102. 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/ Another Slide Just To Talk About flatMap() 44 flatMap() is nothing more than the functional alternative to RPC. Just a way to say “Ok bind this incoming data to this sub-flow and listen for the result, dude”.
  103. 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/ Another Slide Just To Talk About flatMap() 45
  104. 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/ Another Slide Just To Talk About flatMap() 45 Usually in Functional Reactive Programming, flatMap is often used for crossing an async boundary.
  105. 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/ Another Slide Just To Talk About flatMap() 46
  106. 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/ Another Slide Just To Talk About flatMap() 46 This applies to Reactor too, but ALL Reactor actions also have built-in backpressure support and dispatching facilities
  107. Streams.just('doge’).flatMap{ name -> Streams.just(name) .observe{ println 'so wow' } .map{

    'much monad'} }.consume{ assert it == 'much monad' } 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/ Before you miss it, a FlatMap example 47
  108. Streams.just('doge’).flatMap{ name -> Streams.just(name) .observe{ println 'so wow' } .map{

    'much monad'} }.consume{ assert it == 'much monad' } 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/ Before you miss it, a FlatMap example 47 Feed a dynamic Sub-Stream with a name
  109. Streams.just('doge’).flatMap{ name -> Streams.just(name) .observe{ println 'so wow' } .map{

    'much monad'} }.consume{ assert it == 'much monad' } 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/ Before you miss it, a FlatMap example 47 Feed a dynamic Sub-Stream with a name Sub-Stream definition
  110. Streams.just('doge’).flatMap{ name -> Streams.just(name) .observe{ println 'so wow' } .map{

    'much monad'} }.consume{ assert it == 'much monad' } 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/ Before you miss it, a FlatMap example 47 Feed a dynamic Sub-Stream with a name Sub-Stream definition Sub-Stream result is merged back to the top-level Steam
  111. deferred = Streams.<String>defer(Environment.get()); deferred .partition(8).consume(stream -> stream .dispatchOn(cachedDispatcher()) .map(i ->

    i) .reduce(2, service::reducePairAsMap) .consume(service::forwardToOutput) ); 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/ Doing IO work (esp. O) : Cloning Pipeline 48
  112. deferred = Streams.<String>defer(Environment.get()); deferred .partition(8).consume(stream -> stream .dispatchOn(cachedDispatcher()) .map(i ->

    i) .reduce(2, service::reducePairAsMap) .consume(service::forwardToOutput) ); 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/ Doing IO work (esp. O) : Cloning Pipeline 48 Will create 8 clones competing for upstream data
  113. deferred = Streams.<String>defer(Environment.get()); deferred .partition(8).consume(stream -> stream .dispatchOn(cachedDispatcher()) .map(i ->

    i) .reduce(2, service::reducePairAsMap) .consume(service::forwardToOutput) ); 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/ Doing IO work (esp. O) : Cloning Pipeline 48 Will create 8 clones competing for upstream data Start consuming the full Stream until complete
  114. Streams.range(1, Integer.MAX_VALUE) .requestOn(Environment.masterDispatcher()) .sample(2l, TimeUnit.SECONDS) .dispatchOn(Environment.cachedDispatcher()) .consume{ println it }

    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/ Dealing with a nervous Publisher 49
  115. Streams.range(1, Integer.MAX_VALUE) .requestOn(Environment.masterDispatcher()) .sample(2l, TimeUnit.SECONDS) .dispatchOn(Environment.cachedDispatcher()) .consume{ println it }

    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/ Dealing with a nervous Publisher 49 An intense publisher
  116. Streams.range(1, Integer.MAX_VALUE) .requestOn(Environment.masterDispatcher()) .sample(2l, TimeUnit.SECONDS) .dispatchOn(Environment.cachedDispatcher()) .consume{ println it }

    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/ Dealing with a nervous Publisher 49 An intense publisher Assigned with a global dispatcher
  117. Streams.range(1, Integer.MAX_VALUE) .requestOn(Environment.masterDispatcher()) .sample(2l, TimeUnit.SECONDS) .dispatchOn(Environment.cachedDispatcher()) .consume{ println it }

    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/ Dealing with a nervous Publisher 49 An intense publisher Assigned with a global dispatcher Retaining a single value every 2s
  118. Streams.range(1, Integer.MAX_VALUE) .requestOn(Environment.masterDispatcher()) .sample(2l, TimeUnit.SECONDS) .dispatchOn(Environment.cachedDispatcher()) .consume{ println it }

    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/ Dealing with a nervous Publisher 49 An intense publisher Assigned with a global dispatcher Retaining a single value every 2s Dispatching the samples with a different dispatcher to avoid publisher contention
  119. def closeCircuit = stream def openCircuit = fallback ?: Streams.<T>fail(new

    Exception("service unavailable")) def circuitSwitcher = Streams.switchOnNext() stream .materialize() .window(maxSignals, maxTime) .flatMap{ s -> s.reduce(metrics){ tuple -> if(tuple.t1.isOnNext()) tuple.t2.incrementSuccess() else if(tuple.t1.isOnError()) tuple.t2.incrementFailure() } } .consume({ metrics -> if(metrics.isOpen()) { Streams.timer(metrics.retryTimeout).consume{ circuitSwitcher.onNext(closeCircuit) } circuitSwitcher.onNext(openCircuit) } else { circuitSwitcher.onNext(closeCircuit) } }, circuitSwitcher.&onError, circuitSwitcher.&onComplete) //start with close circuit circuitSwitcher.onNext(closeCircuit) circuitSwitcher 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/ Failproof: Implementing a Circuit Breaker 50
  120. def closeCircuit = stream def openCircuit = fallback ?: Streams.<T>fail(new

    Exception("service unavailable")) def circuitSwitcher = Streams.switchOnNext() stream .materialize() .window(maxSignals, maxTime) .flatMap{ s -> s.reduce(metrics){ tuple -> if(tuple.t1.isOnNext()) tuple.t2.incrementSuccess() else if(tuple.t1.isOnError()) tuple.t2.incrementFailure() } } .consume({ metrics -> if(metrics.isOpen()) { Streams.timer(metrics.retryTimeout).consume{ circuitSwitcher.onNext(closeCircuit) } circuitSwitcher.onNext(openCircuit) } else { circuitSwitcher.onNext(closeCircuit) } }, circuitSwitcher.&onError, circuitSwitcher.&onComplete) //start with close circuit circuitSwitcher.onNext(closeCircuit) circuitSwitcher TL;DR 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/ Failproof: Implementing a Circuit Breaker 50
  121. def closeCircuit = stream def openCircuit = fallback ?: Streams.<T>fail(new

    Exception("service unavailable")) def circuitSwitcher = Streams.switchOnNext() stream .materialize() .window(maxSignals, maxTime) .flatMap{ s -> s.reduce(metrics){ tuple -> if(tuple.t1.isOnNext()) tuple.t2.incrementSuccess() else if(tuple.t1.isOnError()) tuple.t2.incrementFailure() } } .consume({ metrics -> if(metrics.isOpen()) { Streams.timer(metrics.retryTimeout).consume{ circuitSwitcher.onNext(closeCircuit) } circuitSwitcher.onNext(openCircuit) } else { circuitSwitcher.onNext(closeCircuit) } }, circuitSwitcher.&onError, circuitSwitcher.&onComplete) //start with close circuit circuitSwitcher.onNext(closeCircuit) circuitSwitcher TL;DR 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/ Failproof: Implementing a Circuit Breaker 50 materialize
  122. def closeCircuit = stream def openCircuit = fallback ?: Streams.<T>fail(new

    Exception("service unavailable")) def circuitSwitcher = Streams.switchOnNext() stream .materialize() .window(maxSignals, maxTime) .flatMap{ s -> s.reduce(metrics){ tuple -> if(tuple.t1.isOnNext()) tuple.t2.incrementSuccess() else if(tuple.t1.isOnError()) tuple.t2.incrementFailure() } } .consume({ metrics -> if(metrics.isOpen()) { Streams.timer(metrics.retryTimeout).consume{ circuitSwitcher.onNext(closeCircuit) } circuitSwitcher.onNext(openCircuit) } else { circuitSwitcher.onNext(closeCircuit) } }, circuitSwitcher.&onError, circuitSwitcher.&onComplete) //start with close circuit circuitSwitcher.onNext(closeCircuit) circuitSwitcher TL;DR 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/ Failproof: Implementing a Circuit Breaker 50 materialize window
  123. def closeCircuit = stream def openCircuit = fallback ?: Streams.<T>fail(new

    Exception("service unavailable")) def circuitSwitcher = Streams.switchOnNext() stream .materialize() .window(maxSignals, maxTime) .flatMap{ s -> s.reduce(metrics){ tuple -> if(tuple.t1.isOnNext()) tuple.t2.incrementSuccess() else if(tuple.t1.isOnError()) tuple.t2.incrementFailure() } } .consume({ metrics -> if(metrics.isOpen()) { Streams.timer(metrics.retryTimeout).consume{ circuitSwitcher.onNext(closeCircuit) } circuitSwitcher.onNext(openCircuit) } else { circuitSwitcher.onNext(closeCircuit) } }, circuitSwitcher.&onError, circuitSwitcher.&onComplete) //start with close circuit circuitSwitcher.onNext(closeCircuit) circuitSwitcher TL;DR 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/ Failproof: Implementing a Circuit Breaker 50 materialize window flatMap
  124. def closeCircuit = stream def openCircuit = fallback ?: Streams.<T>fail(new

    Exception("service unavailable")) def circuitSwitcher = Streams.switchOnNext() stream .materialize() .window(maxSignals, maxTime) .flatMap{ s -> s.reduce(metrics){ tuple -> if(tuple.t1.isOnNext()) tuple.t2.incrementSuccess() else if(tuple.t1.isOnError()) tuple.t2.incrementFailure() } } .consume({ metrics -> if(metrics.isOpen()) { Streams.timer(metrics.retryTimeout).consume{ circuitSwitcher.onNext(closeCircuit) } circuitSwitcher.onNext(openCircuit) } else { circuitSwitcher.onNext(closeCircuit) } }, circuitSwitcher.&onError, circuitSwitcher.&onComplete) //start with close circuit circuitSwitcher.onNext(closeCircuit) circuitSwitcher TL;DR 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/ Failproof: Implementing a Circuit Breaker 50 materialize window flatMap reduce
  125. def closeCircuit = stream def openCircuit = fallback ?: Streams.<T>fail(new

    Exception("service unavailable")) def circuitSwitcher = Streams.switchOnNext() stream .materialize() .window(maxSignals, maxTime) .flatMap{ s -> s.reduce(metrics){ tuple -> if(tuple.t1.isOnNext()) tuple.t2.incrementSuccess() else if(tuple.t1.isOnError()) tuple.t2.incrementFailure() } } .consume({ metrics -> if(metrics.isOpen()) { Streams.timer(metrics.retryTimeout).consume{ circuitSwitcher.onNext(closeCircuit) } circuitSwitcher.onNext(openCircuit) } else { circuitSwitcher.onNext(closeCircuit) } }, circuitSwitcher.&onError, circuitSwitcher.&onComplete) //start with close circuit circuitSwitcher.onNext(closeCircuit) circuitSwitcher TL;DR 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/ Failproof: Implementing a Circuit Breaker 50 materialize window flatMap reduce switchOnNext
  126. def closeCircuit = stream def openCircuit = fallback ?: Streams.<T>fail(new

    Exception("service unavailable")) def circuitSwitcher = Streams.switchOnNext() stream .materialize() .window(maxSignals, maxTime) .flatMap{ s -> s.reduce(metrics){ tuple -> if(tuple.t1.isOnNext()) tuple.t2.incrementSuccess() else if(tuple.t1.isOnError()) tuple.t2.incrementFailure() } } .consume({ metrics -> if(metrics.isOpen()) { Streams.timer(metrics.retryTimeout).consume{ circuitSwitcher.onNext(closeCircuit) } circuitSwitcher.onNext(openCircuit) } else { circuitSwitcher.onNext(closeCircuit) } }, circuitSwitcher.&onError, circuitSwitcher.&onComplete) //start with close circuit circuitSwitcher.onNext(closeCircuit) circuitSwitcher TL;DR 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/ Failproof: Implementing a Circuit Breaker 50 materialize window flatMap reduce switchOnNext timer
  127. def fallback = Streams.<String>fail(new Exception("Fast fail”)) //Open the circuit if

    there were more than 50% errors over 5 elements or within 3 sec. //Will automatically close the circuit again after 2 sec. Streams.circuitBreaker(stream, fallback, 5, 3, 0.5, 2) .retryWhen{ s -> s.zipWith(Streams.range(1,3)){ tuple.t2 } .flatMap{ Streams.timer(it) } } .consume ( { println it }, { println it.message }, { println errors } ) 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/ Failproof: Implementing a Circuit Breaker 51
  128. def fallback = Streams.<String>fail(new Exception("Fast fail”)) //Open the circuit if

    there were more than 50% errors over 5 elements or within 3 sec. //Will automatically close the circuit again after 2 sec. Streams.circuitBreaker(stream, fallback, 5, 3, 0.5, 2) .retryWhen{ s -> s.zipWith(Streams.range(1,3)){ tuple.t2 } .flatMap{ Streams.timer(it) } } .consume ( { println it }, { println it.message }, { println errors } ) 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/ Failproof: Implementing a Circuit Breaker 51 Coming soon™ in M2
  129. 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/ DEMO [if time left > 1.mn] 52
  130. 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/ Featuring…. 53 RabbitMQ Ratpack Reactor Stream Websocket client (RxJS + Angular)
  131. 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/ Featuring…. 53 RabbitMQ Ratpack Reactor Stream Websocket client (RxJS + Angular)
  132. 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/ Featuring…. 53 RabbitMQ Ratpack Reactor Stream Websocket client (RxJS + Angular)
  133. 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/ Featuring…. 53 RabbitMQ Ratpack Reactor Stream Websocket client (RxJS + Angular)
  134. 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/ Early adopters § Checkpoint • Reactor 2.0.0.M2 (TBA) implements 1.0.0.M3 - TCK OK • Akka Streams 1.0-M1 implements 1.0.0.M1 - TCK OK • RxJava - ReactiveStreams 0.3.0 implements 0.4.0 - TCK OK • Ratpack 0.9.12-SNAPSHOT implements 1.0.0.M1 - TCK OK § Links • https://github.com/Netflix/RxJava • http://typesafe.com/blog/typesafe-announces-akka-streams • https://github.com/reactor/reactor • http://www.ratpack.io/manual/0.9.9/streams.html 54
  135. 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/ ReactiveStreams.onSubscribe(Resources) § www.reactive-streams.org § https://github.com/reactive-streams/reactive-streams § on maven central : 1.0.0.M3 • org.reactivestreams/reactive-streams • org.reactivestreams/reactive-streams-tck 55
  136. 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/ ReactiveStreams.onNext(Roadmap) § Discussed for inclusion in JDK § Close to release: 1.0.0.RC1 • Evaluating TCK before going 1.0 final • Need 3 fully passing implementations before going 1.0.0.RC1 • TCK improvements 56
  137. 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/ Reactor.onSubscribe(Resources) § http://projectreactor.cfapps.io/ § https://github.com/reactor § Twitter: @projectReactor § Blog Post: https://spring.io/blog/2014/10/21/reactor-2-0-0-m1-released-with- reactive-streams-integration § on maven central : 2.0.0.M1, 2.0.0.BUILD-SNAPSHOT • org.projectreactor/reactor 57
  138. 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/ Q & A 58
  139. 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/ session.onComplete() 59