Download - Grails and the Realtime Web

Transcript
Page 1: Grails and the Realtime Web

© 2013 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Grails and the “Real-time web” By Stephane Maldini

Page 2: Grails and the Realtime Web

Prologue

Page 3: Grails and the Realtime Web

Solving a basic problem

“Your valuable users don’t like waiting”

Page 4: Grails and the Realtime Web

The Age of Asynchronous

Fact #1: –  HTTP request thread is critical path –  Do the barely necessary for fast rendering –  If it’s long*, do it in a separate thread

Page 5: Grails and the Realtime Web

The Age of Asynchronous

Fact #2: –  Creating new Threads needs caution –  Context switching hurts performances –  Concurrent programming is tricky*

Page 6: Grails and the Realtime Web

The Age of Asynchronous

Fact #3: –  Burden on your application is never constant –  Scaling Up is a good start… –  …And Scaling Out is only next

Page 7: Grails and the Realtime Web

Dilemma

So I have to use background threads ? But using them might lead to issues and headaches ? And what if I really need to scale out ?

Page 8: Grails and the Realtime Web

Reactive programming

•  Adding a level of indirection : Driving your application with Events

•  Laziness is key •  Scale up/out by tweaking dispatching

Page 9: Grails and the Realtime Web

The big picture

Events Bus

Point to point

Service Consumer

Service Consumer

Service Consumer

Service Consumer

Service Consumer

Application

Page 10: Grails and the Realtime Web

The big picture

Events Bus

Publish/Subscribe

Service Consumer

Service Consumer

Service Consumer

Service Consumer

Service Consumer

Application

Page 11: Grails and the Realtime Web

The big picture

Events Bus

Publish/Subscribe

App

App

App

App

App

Cloud

Page 12: Grails and the Realtime Web

Remember Platform-Core ? Remember Events ?

Page 13: Grails and the Realtime Web

Introducing GRAILS-EVENTS BOOM!

worse slide ever™

Page 14: Grails and the Realtime Web

The new deal •  New features. And quite a few.

–  Streaming data, Selectors, Queue

•  Based on a solid foundation – Reactor –  Where Platform-core Events best ideas have leaked

•  Semantic changes –  But relatively easy migration path

Page 15: Grails and the Realtime Web

So what Grails Events is about

•  Grails Apps and Plugins can use Events to: –  Listen for plugins/app events –  Start simple with in-memory eventing (#uberfastdata) –  Do Asynchronous calls (default) –  Increase in flexibility if required

Page 16: Grails and the Realtime Web

Installing Grails Events •  It’s a binary plugin (!) •  Requires Grails 2.2+

Page 17: Grails and the Realtime Web

Reactor big picture

Page 18: Grails and the Realtime Web

Semantics: Consumer

•  A Consumer: –  Accepts an Event –  Is registered in a Service or Events artifact, or by calling on() –  Can be thread safe

•  Depending on the dispatcher type •  Assuming the consumer is not registered more than once

Page 19: Grails and the Realtime Web

Semantics: Selector

•  A Selector: –  Matches an event key –  Is paired with a consumer during its registration

Page 20: Grails and the Realtime Web

Semantics: Reactor •  A Reactor:

–  Is a dedicated Consumer Registry –  Has an assigned Dispatcher –  Uses a specific Event Router

•  Usually, if the Dispatcher doesn’t need to be adapted, reuse the default reactor grailsReactor

Page 21: Grails and the Realtime Web

Platform Core: Sending Events  

                       def  user  =  new  User(params).save()                            //non-­‐blocking  call,  will  trigger  application  listeners  for  this  topic                          event('mailRegistration',  user)                              //blocking  call  :                          //event('mailRegistration',  user).waitFor()                              //can  also  be  written  like  that                          //event  topic:'mailRegistration',  data:user                              //and  if  you  need  to  reuse  the  current  thread                          //event  topic:'mailRegistration',  data:user,  fork:false                              render(view:'sendingRegistrationMail’)  

Page 22: Grails and the Realtime Web

Events: Sending Events                              def  user  =  new  User(params).save()                            //non-­‐blocking  call,  will  trigger  application  listeners  for  this  topic                          event('mailRegistration',  user)                              //Do  things  on  each  reply  :                          //event('mailRegistration',  user){  

       if(it  ==  ‘end’){                                    cancel()                                }  

 }                                //can  also  be  written  like  that                          //event  key:'mailRegistration',  data:user                                render(view:'sendingRegistrationMail')                    

Page 23: Grails and the Realtime Web

Platform Core Events : Consuming Events class  UserService{            //use  method  name  'mailRegistration'  as  topic  name        //can  also  use  custom  topic  name  using  topic  arg:  @Listener(topic='test')        @grails.events.Listener        def  mailRegistration(User  user){                    sendMail{                          to  user.mail                          subject  "Confirmation"                          html  g.render(template:"userMailConfirmation")                  }      }          //Can  also  receive  an  EventMessage  to  get  more  information  on  this  particular  event)      @grails.events.Listener(topic="mailRegistration")      def  mailRegistration2(org.grails.plugin.platform.events.EventMessage  msg){                  sendMail{                        to  msg.data.mail                        subject  "Confirmation"                        html  g.render(template:"userMailConfirmation")                  }      }  }  

Page 24: Grails and the Realtime Web

Events : Consuming Events class  UserService{            //use  method  name  'mailRegistration'  as  topic  name        //can  also  use  custom  topic  name  using  topic  arg:  @Selector(‘test')        @reactor.spring.annotation.Selector        def  mailRegistration(User  user){                    sendMail{                          to  user.mail                          subject  "Confirmation"                          html  g.render(template:"userMailConfirmation")                  }      }          //Can  also  receive  an  Event  to  get  more  information  on  this  particular  event)      @reactor.spring.annotation.Selector("mailRegistration")      def  mailRegistration2(reactor.event.Event  msg){                  sendMail{                        to  msg.data.mail                        subject  "Confirmation"                        html  g.render(template:"userMailConfirmation")                  }      }  }  

Page 25: Grails and the Realtime Web

Events : A new Artifact

Page 26: Grails and the Realtime Web

Reactor awesomeness : Selectors •  Listen for arbitrary keys •  import static reactor.event.selector.Selectors.*

Page 27: Grails and the Realtime Web

Reactor awesomeness : Stream API •  Reactive Extensions programming style •  Avoid callback hell

Page 28: Grails and the Realtime Web

Reactor awesomeness : Promise API •  Grails 2.3 Promises become a Reactor Promises •  Benefits from Dispatcher overriding •  Powerful once Combined with Consumers

Page 29: Grails and the Realtime Web

Reactor awesomeness : Routing •  During event dispatching, consumers list is selected •  Publish Subscribe is the default •  Possible to assign different routing strategy

Page 30: Grails and the Realtime Web

Reactor awesomeness : Extensibility

•  Main extension points: –  Dispatcher, Selector, Registry, EventRouter

•  Metadata in Reactor Events DSL: –  ext(‘someExtension’, [ ‘doStuff’ : true ])

Page 31: Grails and the Realtime Web

GORM events •  GORM is now an extension

–  Using ext(‘gorm’, true) on any candidate reactor –  Applicable Selectors: simple topic form (beforeInsert...) –  A boolean reply is evaluated as a cancel directive

Page 32: Grails and the Realtime Web

GRAILS-EVENTS-PUSH Eventing over HTTP

Page 33: Grails and the Realtime Web

An elegant solution to browser push •  Powered by Atmosphere 2 •  Automatically picks an adapted protocol:

–  WebSockets, ServerSideEvent, Streaming, Polling… •  Consumer bridges for server-to-client push •  Reactor bridge for client-to-server push •  Javascript library

Page 34: Grails and the Realtime Web

Installing Grails Events Push 1.  Install Grails Events plugin 2.  Install Grails Events Push plugin

Page 35: Grails and the Realtime Web

Generating Simple Browsers bridges

Page 36: Grails and the Realtime Web

React on server side events

Page 37: Grails and the Realtime Web

Generating Advanced Browsers bridges

Page 38: Grails and the Realtime Web

DEMO Burn some idols for the demo gods please

Page 39: Grails and the Realtime Web

Epilogue

Page 40: Grails and the Realtime Web

The Bad Stuff •  events-si : Events API on top of Spring Integration

–  Not here (just) yet

•  events-vertx : Abandoned experiment –  Working around Distributed Reactor

•  Stream DSL could be optimized –  Reducing the number of objects

Page 41: Grails and the Realtime Web

Roadmap •  events:

–  Document, especially for Migration from Platform Core –  Stick with latest awesome features from Reactor

•  Still Many API to expose: Processors, Buffer, TCP, Queues, Sequencer…

•  events-push -> events-atmosphere : –  More robust subscription mech –  Update atmosphere client –  Add support for replyTo –  Add support for binary

Page 42: Grails and the Realtime Web

Roadmap •  events-sockjs:

–  Involves Reactor work here •  events-si:

–  Supports new events plugin

•  events-xx: –  The plugin where you are the hero

Page 43: Grails and the Realtime Web

Learn More. Stay Connected.

•  Follow-up

–  Reactor repository: http://github.com/reactor/ –  Mail: @smaldini / [email protected]

•  Talk to us on Twitter: @springcentral •  Find Session replays on YouTube: spring.io/video