Typesafe Webinar: Going Reactive with Java 8

4,391 views

Published on

Java 8's lambdas make building Reactive applications a whole lot easier and cleaner. Through copious code examples this session will show you how to build event-driven, scalable, resilient, and responsive applications with Java 8, Play Framework and Akka. On the web side you will learn about using lambdas for async & non-blocking requests & WebSockets. You will also learn how the actor model in Akka pairs well with lambdas to create an event-driven foundation that provides concurrency, clustering and fault-tolerance.

Published in: Technology

Typesafe Webinar: Going Reactive with Java 8

  1. 1. Going Reactive with Java 8 Ryan Knight& Björn Antonsson
  2. 2. Users Want In-SyncData Real-time Collaboration InstantFeedback To NotWait
  3. 3. Users Want Reactive Apps www.ReactiveManifesto.org
  4. 4. Reactive Web Apps with Play Framework http://www.playframework.com
  5. 5. Reactive Web Apps with Play Framework Reactive Requests Reactive Composition Reactive Push 2-Way Reactive
  6. 6. Routes Declarative, Type-safe URLMapping VERB PATH CONTROLLER_METHOD GET / controllers.Application.index() GET /foo controllers.Application.foo()
  7. 7. Controllers Synchronous Request Usefulforrequests thatdon`thave anything to notblock on publicstaticResultsyncFoo(){ returnok("syncfoo"); }
  8. 8. Reactive Requests
  9. 9. Asynchronous Request Underthe covers Play implements allrequests in this way publicstaticF.Promise<Result>asyncFoo(){ returnF.Promise.promise(()->ok("asyncfoo")); }
  10. 10. Reactive Request (Async + Non- Blocking) Needs to have something to notblock on publicstaticIntegerlongRunningCalculation(){ return(5134*5789)/349; } publicstaticF.Promise<Result>basicPromise(){ F.Promise<Integer>promise=F.Promise.promise(()->longRunningCalculation()); returnpromise.map((Integeri)->ok("Thecalculationresultis:"+i)); }
  11. 11. Reactive Requests Two chained requests (clientto server& serverto typesafe.com) both async& non-blocking publicstaticF.Promise<Result>reactiveRequest(){ F.Promise<WS.Response>typesafePromise=WS.url("http://www.typesafe.com").get(); returntypesafePromise.map(response->ok(response.getBody())); }
  12. 12. Reactive Composition Three requests, two in parrallel(depending on thread availability) allasync& non-blocking publicstaticF.Promise<Result>reactiveComposition(){ finalF.Promise<WS.Response>twitterPromise=WS.url("http://www.twitter.com").get(); finalF.Promise<WS.Response>typesafePromise=WS.url("http://www.typesafe.com").get(); returntwitterPromise.flatMap((twitter)-> typesafePromise.map((typesafe)-> ok(twitter.getBody()+typesafe.getBody()))); }
  13. 13. Reactive Push with SSE Async& Non-Blocking Serverto ClientPush JavaController publicstaticResultevents(){ EventSourceeventSource=newEventSource(){ publicvoidonConnected(){ sendData("hello"); } }; returnok(eventSource); } CoffeeScriptClient events=newEventSource("/events") events.onmessage=(e)-> alert(e.data)
  14. 14. 2-Way Reactive with WebSockets Bi-directionalreactive push JavaControllerwithJava8MethodReference publicstaticWebSocket<String>echo(){ returnnewWebSocket<String>(){ publicvoidonReady(finalIn<String>in,finalOut<String>out){ in.onMessage(out::write); } }; } CoffeeScriptClient ws=newWebSocket("ws://localhost:9000/echo") ws.onmessage=(message)-> console.log(message.data) ws.onopen=()-> ws.send("foo")
  15. 15. Reactive Apps with Akka http://akka.io
  16. 16. Reactive Apps with Akka ActorBased Highly Concurrent Asynchronous Distributable Scales Up & Out
  17. 17. Akka Actor Properties Message Based EventDriven Sane Concurrency Model Non-RequestBased Lifecycle Isolated Failure Handling (Supervision)
  18. 18. Actors with Lambdas Easily define the behaviorof youractor publicstaticclassGreeterextendsAbstractActor{ Stringgreeting=""; publicGreeter(){ receive(ReceiveBuilder. match(WhoToGreet.class,message->greeting="hello,"+message.who). match(Greet.class,message->sender().tell(newGreeting(greeting),self())). build()); } }
  19. 19. Handing off Work Forresponsiveness and/orfaulttolerance publicclassHandoffActorextendsAbstractActor{{ receive(ReceiveBuilder.matchEquals("hello",s->{ ActorRefworker= context().actorOf(Props.create(AbstractActor.class, ()->newAbstractActor(){{ receive(ReceiveBuilder. match(String.class,s->{ //longrunningand/ordangerouscomputation sender().tell(s.toUpperCase(),self()); self().tell(PoisonPill.getInstance(),self()); }).build()); }})); worker.forward(s,context()); }).build()); }}
  20. 20. Supervision with Lambdas Take differentactions depending on the failure privatestaticSupervisorStrategystrategy= newOneForOneStrategy(10,Duration.create("1minute"),DeciderBuilder. match(ArithmeticException.class,e->resume()). match(NullPointerException.class,e->restart()). match(IllegalArgumentException.class,e->stop()). matchAny(o->escalate()).build()); @Override publicSupervisorStrategysupervisorStrategy(){ returnstrategy; }
  21. 21. Changing Behavior with Lambdas Quickly implementchanges in behavior publicclassSwapperextendsAbstractLoggingActor{ publicSwapper(){ receive(ReceiveBuilder. matchEquals(Swap,s->{ log().info("Hi"); context().become(ReceiveBuilder. matchEquals(Swap,x->{ log().info("Ho"); context().unbecome();//gobacktopreviousbehavior }).build(),false);//pushontopandkeepoldbehavior }).build()); } }
  22. 22. Actors as Finite State Machines A Fixed Numberof States Defined Transitions Between States Used to ModelforExample Protocols Processes
  23. 23. Finite State Machines Defining Behaviorin States publicclassBuncherextendsAbstractFSM<State,Data>{{ startWith(Idle,Uninitialized); when(Idle, matchEvent(SetTarget.class,Uninitialized.class, (setTarget,uninitialized)-> stay().using(newTodo(setTarget.getRef(),newLinkedList<>())))); when(Active,Duration.create(1,"second"), matchEvent(Arrays.asList(Flush.class,StateTimeout()),Todo.class, (event,todo)->goTo(Idle).using(todo.copy(newLinkedList<>())))); //...transitionsleftout initialize(); }}
  24. 24. Finite State Machines Defining Transition Behavior publicclassBuncherextendsAbstractFSM<State,Data>{{ startWith(Idle,Uninitialized); //...statebehaviorleftout onTransition( matchState(Active,Idle,()->{ //reusethismatcher finalUnitMatch<Data>m=UnitMatch.create( matchData(Todo.class, todo->todo.getTarget().tell(newBatch(todo.getQueue()),self()))); m.match(stateData()); }). state(Idle,Active,()->{/*Dosomethinghere*/})); initialize(); }}
  25. 25. Interoperability https://github.com/scala/scala-java8-compat
  26. 26. Java Scala Interoperability Seamlessly Work with ScalaFutures importscala.concurrent.*; importstaticscala.compat.java8.JFunction.*; classTest{ privatestaticFuture<Integer>futureExample(Future<String>future,ExecutionContextec){ returnfuture.map(func(s->s.toUpperCase()),ec).map(func(s->s.length()),ec); } }
  27. 27. Java Scala Interoperability Seamlessly ConvertBetween JavaCompletionStage and Scala Future importjava.util.concurrent.CompletionStage; importscala.concurrent.Future; importstaticscala.compat.java8.FutureConverters.*; finalCompletionStage<String>cs=...//fromanasyncJavaAPI finalFuture<String>f=toScala(cs); ... finalFuture<Integer>f2=...//fromanasyncScalaAPI finalCompletionStage<Integer>cs2=toJava(f2);
  28. 28. Demo: Reactive Stocks (Java 8) Getthe ActivatorTemplate: http://typesafe.com/activator/template/reactive-stocks-java8 AkkaActors forthread-safe state and non-requestbased events Play Framework forReactive Composition, Reactive Push, and a JavaScriptUI Reactive Stocks (Java8)
  29. 29. Get Started with Activator http://typesafe.com/activator/template/hello-akka-java8 http://typesafe.com/activator/template/reactive-java8-play http://typesafe.com/activator/template/akka-supervision-java-lambda http://typesafe.com/activator/template/akka-sample-fsm-java-lambda http://typesafe.com/activator/template/akka-sample-persistence-java-lambda http://typesafe.com/activator/template/reactive-stocks-java8 Hello Akka!(Java8) Go Reactive with Java8 & Play Framework AkkaSupervision in Javawith Lambdas AkkaFSMin Javawith Lambdas AkkaPersistence Samples in Javawith Lambdas Reactive Stocks (Java8)

×