Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.
Groovy, Reactor, Grails 

& the realtime web
Guillaume Laforge 

@glaforge !

Stéphane Maldini

@smaldini !
Stéphane
Maldini
Consultant and Reactor committer
at
.
!

@smaldini
1
t
r
a
P

Reactor
Reactor — Housekeeping
!

• Tweet questions during the presentation	

– @ProjectReactor
!

• Stop us anywhere if you have ...
Reactor — Reactive Architecture ?
REACTIVE
AGILE
EVENT DRIVEN
SCALABLE
AVAILABLE

@glaforge — @smaldini / #DV13-rtweb

!5
Reactor — Reactive Architecture ?
• A good description is available on: 

http://www.reactivemanifesto.org/	

!

• Functio...
Reactor — Threading model matters
• Context switching hurts performances	

• Locking hurts performances	

• Message passin...
Reactor — Dealing with performances
• Actors solve the locking and context switching issues 

by becoming state boxes	

• ...
Reactor — LMAX Disruptor and Ring Buffer
• LMAX Disruptor deals with message passing issues	

• Based on a Ring Buffer str...
Reactor — Disruptor performances

@glaforge — @smaldini / #DV13-rtweb

!10
Reactor — Trisha’s pretty picture of Disruptor
http://mechanitis.blogspot.co.uk/2011/07/dissectingdisruptor-writing-to-rin...
Reactor — In love with Disruptor
• Reactor best performances are derived from LMAX Disruptor	

!

• LMAX Disruptor can be ...
Reactor — A foundation part of Spring IO

@glaforge — @smaldini / #DV13-rtweb

!13
Reactor — What is it?
!

• Reactor is a distillation of other libraries and best-practices	

– Elements of other patterns ...
Reactor — What can I build with it?
• Reactor applications are reactive	

– Reactive Extensions in .NET	

– Netflix RxJava	...
Reactor — Landscape

@glaforge — @smaldini / #DV13-rtweb

!16
Reactor — What does it look like?
Create a reactor context
def	
  env	
  =	
  new	
  Environment()	
  
!

Build a reactor
...
Reactor — Selectors
• Selectors are the left-hand side of an equality comparison	

!

– A Selector can be created from any...
Reactor — RegexSelector
• A RegexSelector will match a String by executing the regex
over it	

– R(“some.(.*)”)
– Selector...
Reactor — RegexSelector
!

• A RegexSelector will match a String 

by executing the regex over it	

!

– R(“some.(.*)”)
!
...
Reactor — RegexSelector
Use a Regex Selector and capture group
reactor.on(R('some.(.+)')){	
  Event<String>	
  ev	
  -­‐>	...
Reactor — UriSelector
• A UriTemplateSelector will match a String 

by extracting bits from a URI
!

– U(“/some/{path}”)
–...
Reactor — UriSelector
Use a URI Selector and capture fragment
reactor.on(U('/some/**/{topic}')){	
  Event<String>	
  ev	
 ...
Reactor — Consumer, Function, Supplier, Predicate
public	
  interface	
  Consumer<T>	
  {	
  
	
  	
  	
  	
  	
  	
  	
  ...
Reactor — Streams
●

−
−

Streams allow for composition of functions on data	

Callback++	

Netflix RxJava Observable, JDK ...
Reactor — Promises
●

−
−

Promises supersedes Java Future for composition	

Share common functions with Stream
Stateful: ...
Reactor — Processor
●

−
−

Thin wrapper around Disruptor RingBuffer
Converts Disruptor API to Reactor API	

Uber fast per...
Reactor — Spring
!

Helpers to integrate Reactor into ApplicationContext	


●

!

−

@EnableReactor for easy configuration	...
Reactor — Spring
Setup Environment

@Configuration	
  
@EnableReactor	
  
class	
  ReactorConfiguration	
  {	
  
!

	
  	
...
Reactor — Spring
@Component	
  
class	
  SimpleHandler	
  {	
  

Inject reactor

!

	
  	
  @Autowired	
  Reactor	
  react...
Reactor — Spring
●

−
−
●
●

●

DispatcherTaskExecutor 	

Not really a high-scale TaskExecutor	

Used to get Spring compon...
Reactor — Groovy
●

−
−
−
−

First class citizen language implementation	

@CompileStatic ready	

Prominent use of Closure...
Reactor — Groovy
Works with Groovy 2 CompileStatic

Coerce String to $(string)

@CompileStatic	
  
def	
  welcome()	
  {	
...
Reactor — Groovy Promises and Streams
Build an async function

def	
  promise	
  =	
  Promises.task	
  {	
  longStuff();	
...
Reactor — Groovy Environment
Works with Groovy 2
@CompileStatic

Prepare an environment
builder

GroovyEnvironment.create	...
Reactor — Groovy Environment
Build a named Reactor

GroovyEnvironment.create	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  reac...
Reactor — Extensive Awesomeness
●

TCP Client/Server, with a Netty 4 implementation	


●

Buffer tools	


●

Sequencer sup...
Reactor — Roadmap
1.1 discussions

●

−

StateBox: a safe tool for concurrent writes	


−

Better Timer management	


−

S...
Reactor — Roadmap
1.1 discussions

●

−

HTTP helpers

−

Improved RingBuffer API for multithreaded consumers
(slow consum...
Reactor — Uber Community Contribs
●

−

Meltdown: A Clojure binding by @michaelklishin &
@ifesdjeen 	

https://github.com/...
Reactor — Uber Community Contribs
!

●

−

High Performance Couchbase ingestion by @daschl	

http://nitschinger.at/Using-t...
Demo
2
t
r
a
P

Grails
Grails — The Age of Asynchronous
Fact #1:	

– HTTP request thread is critical path	

– Do the barely necessary for fast re...
Grails — The Age of Asynchronous
Fact #2:	

– Creating new Threads needs caution	

– Context switching hurts performances	...
Grails — The Age of Asynchronous

Fact #3:	

– Burden on your application is never constant	

– Scaling Up is a good start...
Grails — The Age of Asynchronous

So I have to use background threads ?	

But using them might lead to issues and headache...
Grails — Reactive Programming Recap
• Adding a level of indirection : 

Driving your application with Events
• Laziness is...
Grails — The Big Picture
Application
Service
Consumer
Service
Consumer

Publish/Subscribe
Events
Bus

Service
Consumer

@g...
Grails — The Big Picture
Cloud
App
Publish/Subscribe

App
Events
Bus

App

App
App

@glaforge — @smaldini / #DV13-rtweb

!...
Introducing	
  GRAILS-­‐EVENTS	
  plugin
BOOM!

worse slide ever™
@glaforge — @smaldini / #DV13-rtweb

!51
Grails — Origins : Platform-Core plugin
• An initiative to provide modern tools for grails development	

!

• Among them: ...
Grails — Why a new plugin ?
• New features. And quite a few.	

– Streaming data, Selectors, Queue	

!

• Based on a new so...
Grails — Why a new plugin ?
• Lightweight, only focused on events	

!

• Ready to be embedded in a future Grails version	
...
Grails — So what Grails Events is about
• Grails Apps and Plugins can use Events to:	

– Listen for plugins/app events	

–...
Grails — Installing Grails Events
• It’s a binary plugin (!)	

• Requires Grails 2.2+
repositories	
  {	
  
	
  	
  	
  	
...
Grails — Semantics: Consumer
• A Consumer:	

– Accepts an Event	

– Is registered in a Service or Events artifact, or by c...
Grails — Semantics: Selector
• A Selector:	

– Matches an event key	

– Is paired with a consumer during its registration
...
Grails — Semantics: Reactor
• A Reactor:	

– Is a dedicated Consumer Registry	

– Has an assigned Dispatcher	

– Uses a sp...
Grails — Pattern Examples : Event Driven CQRS
http://martinfowler.com/bliki/CQRS.html

Save a GORM entity
SaveService
GORM...
Grails — Pattern Examples : Modular Architecture
Core application untouched

Trigger ‘request’ event

Main Application

Re...
Grails — Pattern Examples : Background Processing
Return immediately
Grails Controller

REST service

Request Service

HTT...
Grails — Sending Events (grails-platform-core)
def	
  user	
  =	
  new	
  User(params).save()	
  
!

event('mailRegistrati...
Grails — Sending Events (grails-events)
def	
  user	
  =	
  new	
  User(params).save()	
  
!

event('mailRegistration',	
 ...
Grails — Consuming Events (grails-platform-core)
class	
  UserService{	
  
	
  	
  	
  	
  @grails.events.Listener	
  
	
 ...
Grails — Consuming Events (grails-events)
Consume on
Selector(method name)

class	
  UserService{	
  
	
  	
  
	
  	
  	
 ...
Grails — A new Artifact conf/XxxxEvents
includes	
  =	
  ['default']	
  

Merge with DefaultsEvents

!

doWithReactor	
  =...
Grails — Reactor awesomeness : Selectors
• Listen for arbitrary keys	

• import static reactor.event.selector.Selectors.*
...
Grails — Reactor awesomeness : Stream API
• Reactive Extensions programming style	

• Avoid callback hell
Build a Stream t...
Grails — Reactor awesomeness: Promise API
• Grails 2.3 Promises become a Reactor Promises	

• Benefits from Dispatcher over...
Grails — Reactor awesomeness : Routing
• During event dispatching, consumers list is selected	

• Publish Subscribe is the...
Grails — Extensibility
!

• Main extension points:	

– Dispatcher, Selector, Registry, EventRouter, Consumer
!

• Metadata...
Grails — GORM events
• GORM is now an extension	

– Using ext(‘gorm’, true) on any candidate reactor	

– Applicable Select...
GRAILS-­‐EVENTS-­‐PUSH	
  plugin
Eventing over HTTP!

@glaforge — @smaldini / #DV13-rtweb

!74
Grails — Pattern Examples : “Realtime” web
Push reply to browser: Websocket, SSE, long-polling…

Reply a new event

Respon...
Grails — An elegant solution to browser push
• Powered by Atmosphere 2	

• Automatically picks an adapted protocol:	

– We...
Grails — Installing Grails Events Push
1. Install Grails Events plugin	

2. Install Grails Events Push plugin
grails.servl...
Grails — grails-events-push Lifecycle 1 - Handshake

Browser

EventsPushHandler

Adapt Protocol and Open
new persistent co...
Grails — grails-events-push Lifecycle 2 - Register
Consumer registered on all Reactor with
‘browser’ extension enabled
Bro...
Grails — grails-events-push Lifecycle 3 - Notify
RequestService consumes on matching
Selector within the ‘browser’ Reactor...
Grails — grails-events-push Lifecycle 4 - Consume
Notify ‘browser’ enabled
Reactor and match key
Browser

Reactor(s)

Resp...
Grails — Generating Simple Browsers bridges
includes	
  =	
  'push'	
  
!

Conventional name to
override ‘browser’ reactor...
Grails — React on server side events
Inject grailsEvents.js (requires resources plugin)
Create a connection
between the br...
Grails — Generating Advanced Browsers bridges
includes	
  =	
  ['push']	
  
!

Include PushEvents (configure a
reactor for...
Grails — The Bad Stuff
• events-si : Events API on top of Spring Integration	

– Not here (just) yet	

!

• events-vertx :...
Grails — Roadmap
• events: 	

– Document, especially for Migration from Platform Core	

– Stick with latest awesome featur...
Grails — Roadmap
• events-sockjs:	

– Involves Reactor work here 	

!

• events-si: 	

– Supports new events plugin	

!

•...
Demo
4
t
r
a
P

Summary
Groovy, Reactor, Grails and the realtime web
• Embrace modern reactive architectures with Groovy,
Reactor and Grails!	

• ...
Nächste SlideShare
Wird geladen in …5
×

Reactor grails realtime web devoxx 2013

3.816 Aufrufe

Veröffentlicht am

Veröffentlicht in: Technologie
  • Als Erste(r) kommentieren

Reactor grails realtime web devoxx 2013

  1. 1. Groovy, Reactor, Grails 
 & the realtime web Guillaume Laforge 
 @glaforge ! Stéphane Maldini
 @smaldini !
  2. 2. Stéphane Maldini Consultant and Reactor committer at . ! @smaldini
  3. 3. 1 t r a P Reactor
  4. 4. Reactor — Housekeeping ! • Tweet questions during the presentation – @ProjectReactor ! • Stop us anywhere if you have a question – There are no stupid questions, only stupid answers! @glaforge — @smaldini / #DV13-rtweb !4
  5. 5. Reactor — Reactive Architecture ? REACTIVE AGILE EVENT DRIVEN SCALABLE AVAILABLE @glaforge — @smaldini / #DV13-rtweb !5
  6. 6. Reactor — Reactive Architecture ? • A good description is available on: 
 http://www.reactivemanifesto.org/ ! • Functional Programming helps as it is stimulus based by nature ! • Groovy is a perfect candidate: 
 Closures and DSL are first class citizen ! • Reactor completes the picture by providing abstractions @glaforge — @smaldini / #DV13-rtweb !6
  7. 7. Reactor — Threading model matters • Context switching hurts performances • Locking hurts performances • Message passing hurts performances • Blocking for a thread hurts performances • Creating Threads needs memory @glaforge — @smaldini / #DV13-rtweb !7
  8. 8. Reactor — Dealing with performances • Actors solve the locking and context switching issues 
 by becoming state boxes • One thread assigned per consumer • One thread will ever access a property
 • Non Blocking Programming solves thread creation and waiting issues by delaying logic • Callback will be executed when possible (Lazy) • Reallocate the blocking time to process something else @glaforge — @smaldini / #DV13-rtweb !8
  9. 9. Reactor — LMAX Disruptor and Ring Buffer • LMAX Disruptor deals with message passing issues • Based on a Ring Buffer structure • “Mechanical Sympathy” in Disruptor ! • http://lmax-exchange.github.com/disruptor/files/ Disruptor-1.0.pdf • http://mechanitis.blogspot.co.uk/2011/06/dissecting-disruptorwhats-so-special.html @glaforge — @smaldini / #DV13-rtweb !9
  10. 10. Reactor — Disruptor performances @glaforge — @smaldini / #DV13-rtweb !10
  11. 11. Reactor — Trisha’s pretty picture of Disruptor http://mechanitis.blogspot.co.uk/2011/07/dissectingdisruptor-writing-to-ring.html @glaforge — @smaldini / #DV13-rtweb !11
  12. 12. Reactor — In love with Disruptor • Reactor best performances are derived from LMAX Disruptor ! • LMAX Disruptor can be considered 
 as an evolution of the Actor Model: ! • Still avoid locking and deals with context switching • Producer/Consumer decoupled • Add Pipelining, Batching and more @glaforge — @smaldini / #DV13-rtweb !12
  13. 13. Reactor — A foundation part of Spring IO @glaforge — @smaldini / #DV13-rtweb !13
  14. 14. Reactor — What is it? ! • Reactor is a distillation of other libraries and best-practices – Elements of other patterns and libraries 
 surface throughout Reactor's abstractions ! • http://stackoverflow.com/questions/16595393/akka-or-reactor @glaforge — @smaldini / #DV13-rtweb !14
  15. 15. Reactor — What can I build with it? • Reactor applications are reactive – Reactive Extensions in .NET – Netflix RxJava – Observer pattern ! • Reactor applications route events based on a Selector – Like a routing topic, but can be any object – Regex, URI template, Class.isAssingableFrom, custom logic @glaforge — @smaldini / #DV13-rtweb !15
  16. 16. Reactor — Landscape @glaforge — @smaldini / #DV13-rtweb !16
  17. 17. Reactor — What does it look like? Create a reactor context def  env  =  new  Environment()   ! Build a reactor parameter def  reactor  =   Reactors.reactor().env(env).dispatcher(RING_BUFFER).get()   ! reactor.on($('topic')){  Event<String>  ev  -­‐>                  println  "Hello  $ev.data"   }   React on ‘topic’ events ! reactor.notify('topic',  Event.wrap('John  Doe')) Trigger reactor ‘topic’ key @glaforge — @smaldini / #DV13-rtweb !17
  18. 18. Reactor — Selectors • Selectors are the left-hand side of an equality comparison ! – A Selector can be created from any object using $(obj) 
 (or the long form: Selectors.object(obj)) ! – A Selector can extract data from the matched key ! – Predicate<T> Selectors can be created to match on domainspecific criteria like header values @glaforge — @smaldini / #DV13-rtweb !18
  19. 19. Reactor — RegexSelector • A RegexSelector will match a String by executing the regex over it – R(“some.(.*)”) – Selectors.regex(“some.(.*)”) @glaforge — @smaldini / #DV13-rtweb !19
  20. 20. Reactor — RegexSelector ! • A RegexSelector will match a String 
 by executing the regex over it ! – R(“some.(.*)”) ! – Selectors.regex(“some.(.*)”) @glaforge — @smaldini / #DV13-rtweb !20
  21. 21. Reactor — RegexSelector Use a Regex Selector and capture group reactor.on(R('some.(.+)')){  Event<String>  ev  -­‐>                  def  s  =  ev.headers.get('group1')   }                                 s will be ‘topic’ ! reactor.notify('some.topic',  Event.wrap('John  Doe')) Notify a simple String key to be matched @glaforge — @smaldini / #DV13-rtweb !21
  22. 22. Reactor — UriSelector • A UriTemplateSelector will match a String 
 by extracting bits from a URI ! – U(“/some/{path}”) – Selectors.uri(“/some/{path}”) @glaforge — @smaldini / #DV13-rtweb !22
  23. 23. Reactor — UriSelector Use a URI Selector and capture fragment reactor.on(U('/some/**/{topic}')){  Event<String>  ev  -­‐>                  def  s  =  ev.headers['topic']   }                 s will be ‘topic’ ! reactor.notify('/some/to/topic',  Event.wrap('John  Doe')) Notify a simple String URI key to be matched @glaforge — @smaldini / #DV13-rtweb !23
  24. 24. Reactor — Consumer, Function, Supplier, Predicate public  interface  Consumer<T>  {                  void  accept(T  t);     }                 Generic Callback ! public  interface  Supplier<T>  {                    T  get();       }   Object Factory ! public  interface  Function<T,  V>  {                  V  apply(T  t);   }                 Map Operation ! public  abstract  class  Predicate<T>  {                    boolean  test(T  t);     }       @glaforge — @smaldini / #DV13-rtweb Filter Operation !24
  25. 25. Reactor — Streams ● − − Streams allow for composition of functions on data Callback++ Netflix RxJava Observable, JDK 8 Stream Stream<String>  str  =  obtainStream()   Coerces to Function ! str.map{  it.toUpperCase()  }                  .filter{  someCondition()  }                  .consume{  s  -­‐>  log.info  "consumed  string  $s"  } Coerces to Predicate @glaforge — @smaldini / #DV13-rtweb Coerces to Consumer !25
  26. 26. Reactor — Promises ● − − Promises supersedes Java Future for composition Share common functions with Stream Stateful: only 1 transition allowed Promise<String>  p  =  doLater()   ! String  s  =  p    .onSuccess  {  s  -­‐>  log.info  "consumed  string  $s"  }      .onFailure  {  t  -­‐>  log.error  "$t.message"  }        .onComplete  {  log.info  'complete'  }          .await(5,  SECONDS)   ! p.map{  it.toUpperCase()  }.consume{s  -­‐>  log.info  "UC:  $s"}   Block for a return value @glaforge — @smaldini / #DV13-rtweb !26
  27. 27. Reactor — Processor ● − − Thin wrapper around Disruptor RingBuffer Converts Disruptor API to Reactor API Uber fast performance for #UberFastData Processor<Buffer>  proc   ! Operation<Buffer>  op  =  proc.prepare()   op.get().append(data).flip()   op.commit()   ! proc.batch(512)  {  it.append(data).flip()  } Fill 512 slots and release once @glaforge — @smaldini / #DV13-rtweb !27
  28. 28. Reactor — Spring ! Helpers to integrate Reactor into ApplicationContext ● ! − @EnableReactor for easy configuration ! − Wiring annotated handlers @glaforge — @smaldini / #DV13-rtweb !28
  29. 29. Reactor — Spring Setup Environment @Configuration   @EnableReactor   class  ReactorConfiguration  {   !                @Bean  Reactor  input(Environment  env)  {                                  Reactors.reactor().env(env)                                                  .dispatcher(RING_BUFFER).get()                  }                 !                @Bean  Reactor  output(Environment  env)  {                                  Reactors.reactor().env(env)                                                  .dispatcher(RING_BUFFER).get()                  }                 } @glaforge — @smaldini / #DV13-rtweb !29
  30. 30. Reactor — Spring @Component   class  SimpleHandler  {   Inject reactor !    @Autowired  Reactor  reactor   !    @Selector('test.topic')  void  onTestTopic(String  s)  {                      //  Handle  data      }   } Register consumer on @reactor @glaforge — @smaldini / #DV13-rtweb !30
  31. 31. Reactor — Spring ● − − ● ● ● DispatcherTaskExecutor Not really a high-scale TaskExecutor Used to get Spring components running in same thread as Reactor Consumers ConversionService integration PromiseHandlerMethodReturnValueHandler (!) ReactorSubscribableChannel @glaforge — @smaldini / #DV13-rtweb !31
  32. 32. Reactor — Groovy ● − − − − First class citizen language implementation @CompileStatic ready Prominent use of Closure as Consumers, Functions and more Operator overloading for elegant programming Full Reactor system Builder @glaforge — @smaldini / #DV13-rtweb !32
  33. 33. Reactor — Groovy Works with Groovy 2 CompileStatic Coerce String to $(string) @CompileStatic   def  welcome()  {                  reactor.on('greetings')  {  String  s  -­‐>                                  reply  "hello  $s"                                  reply  "how  are  you?"                  }   Send data back using replyTo key header !                reactor.notify  'greetings',  'Jon'   !                reactor.send('greetings',  'Stephane')  {                                  println  it                                  cancel()                  }   } Stop listening for replies @glaforge — @smaldini / #DV13-rtweb Coerce data arg to Event.wrap(data) Notify & Listen for replies !33
  34. 34. Reactor — Groovy Promises and Streams Build an async function def  promise  =  Promises.task  {  longStuff();  1  }  get()                       ! def  transformation  =  promise  |  {  it  +  1  }   transformation.await()  ==  2             Pipe promise with the ! def  deferredStream  =  Streams.defer().get()               closure transformation (deferredStream  &  {  it  >  2  })  <<  {  send(it)  }   ! deferredStream  <<  1  <<  2  <<  3  <<  4 Filter the stream with the right hand closure predicate @glaforge — @smaldini / #DV13-rtweb Add callback after filter Send data !34
  35. 35. Reactor — Groovy Environment Works with Groovy 2 @CompileStatic Prepare an environment builder GroovyEnvironment.create  {                  environment  {                                  defaultDispatcher  =  "test"   ! which dispatcher to use when creating a reactor                                dispatcher('test')  {                                                  type  =  DispatcherType.SYNCHRONOUS                                  }                  }                 Build a standard }.environment() Return a ready to use Environment @glaforge — @smaldini / #DV13-rtweb Dispatcher !35
  36. 36. Reactor — Groovy Environment Build a named Reactor GroovyEnvironment.create  {                  reactor('test1')  {   Intercept the data                                stream('test')  {                                                                                  consume  {  ev-­‐>                                                           stream coming by the                                                                log.info  ev.data                                       selector $(‘test’)                                                }                                                                              }                                                                                                                                    on('test')  {   Stream builder                                                reply  it                                  }                  }                                                                                                             }   Attach inline consumers @glaforge — @smaldini / #DV13-rtweb !36
  37. 37. Reactor — Extensive Awesomeness ● TCP Client/Server, with a Netty 4 implementation ● Buffer tools ● Sequencer support, for event ordering ● Work Queue support with OoB Java Chronicle implementation ● Log Appender @glaforge — @smaldini / #DV13-rtweb !37
  38. 38. Reactor — Roadmap 1.1 discussions ● − StateBox: a safe tool for concurrent writes − Better Timer management − Spring XD, Spring 4 − Exploring Distributed Reactors ● Voice your interest and your use-case here @glaforge — @smaldini / #DV13-rtweb !38
  39. 39. Reactor — Roadmap 1.1 discussions ● − HTTP helpers − Improved RingBuffer API for multithreaded consumers (slow consumers) − More Groovy Love: Buffer, TCP, Processor, Time, @glaforge — @smaldini / #DV13-rtweb !39
  40. 40. Reactor — Uber Community Contribs ● − Meltdown: A Clojure binding by @michaelklishin & @ifesdjeen https://github.com/clojurewerkz/meltdown @glaforge — @smaldini / #DV13-rtweb !40
  41. 41. Reactor — Uber Community Contribs ! ● − High Performance Couchbase ingestion by @daschl http://nitschinger.at/Using-the-Reactor-Processor-for-HighPerformance-TCP ! ● Benefits of using Reactor Processor, TCP and Batching facilities @glaforge — @smaldini / #DV13-rtweb !41
  42. 42. Demo
  43. 43. 2 t r a P Grails
  44. 44. Grails — 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 @glaforge — @smaldini / #DV13-rtweb !44
  45. 45. Grails — The Age of Asynchronous Fact #2: – Creating new Threads needs caution – Context switching hurts performances – Concurrent programming is tricky* @glaforge — @smaldini / #DV13-rtweb !45
  46. 46. Grails — 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 @glaforge — @smaldini / #DV13-rtweb !46
  47. 47. Grails — The Age of Asynchronous 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 ? @glaforge — @smaldini / #DV13-rtweb !47
  48. 48. Grails — Reactive Programming Recap • Adding a level of indirection : 
 Driving your application with Events • Laziness is key • Scale up/out by tweaking dispatching @glaforge — @smaldini / #DV13-rtweb !48
  49. 49. Grails — The Big Picture Application Service Consumer Service Consumer Publish/Subscribe Events Bus Service Consumer @glaforge — @smaldini / #DV13-rtweb Service Consumer Service Consumer !49
  50. 50. Grails — The Big Picture Cloud App Publish/Subscribe App Events Bus App App App @glaforge — @smaldini / #DV13-rtweb !50
  51. 51. Introducing  GRAILS-­‐EVENTS  plugin BOOM! worse slide ever™ @glaforge — @smaldini / #DV13-rtweb !51
  52. 52. Grails — Origins : Platform-Core plugin • An initiative to provide modern tools for grails development ! • Among them: the Events API • An abstraction used in a few Grails applications today to decouple logic from producers ! • grails-events can be considered as 
 Platform Core Events API 2.0 @glaforge — @smaldini / #DV13-rtweb !52
  53. 53. Grails — Why a new plugin ? • New features. And quite a few. – Streaming data, Selectors, Queue ! • Based on a new solid foundation – Reactor – Where Platform-core Events best ideas have leaked ! • Semantic changes – But relatively straightforward migration path @glaforge — @smaldini / #DV13-rtweb !53
  54. 54. Grails — Why a new plugin ? • Lightweight, only focused on events ! • Ready to be embedded in a future Grails version • Complete the asynchronous story • Could enable runtime plugin deployment @glaforge — @smaldini / #DV13-rtweb !54
  55. 55. Grails — 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 @glaforge — @smaldini / #DV13-rtweb !55
  56. 56. Grails — Installing Grails Events • It’s a binary plugin (!) • Requires Grails 2.2+ repositories  {          //...                mavenRepo  "http://repo.springsource.org/libs-­‐snapshot"          mavenRepo  "http://repo.grails.org/grails/libs-­‐snapshots-­‐local/"   }   ! dependencies  {          compile  'org.grails.plugins:events:1.0.0.BUILD-­‐SNAPSHOT'   }   @glaforge — @smaldini / #DV13-rtweb !56
  57. 57. Grails — 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 @glaforge — @smaldini / #DV13-rtweb !57
  58. 58. Grails — Semantics: Selector • A Selector: – Matches an event key – Is paired with a consumer during its registration – Any bean method can be transformed into consumer with @Selector @glaforge — @smaldini / #DV13-rtweb !58
  59. 59. Grails — 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 @glaforge — @smaldini / #DV13-rtweb !59
  60. 60. Grails — Pattern Examples : Event Driven CQRS http://martinfowler.com/bliki/CQRS.html Save a GORM entity SaveService GORM DB PostProcessingService Insert Record @glaforge — @smaldini / #DV13-rtweb Trigger afterInsert event Consume afterInsert events !60
  61. 61. Grails — Pattern Examples : Modular Architecture Core application untouched Trigger ‘request’ event Main Application RequestService Notification Plugin NotificationService Create a decoupled module @glaforge — @smaldini / #DV13-rtweb Consume ‘request’ events !61
  62. 62. Grails — Pattern Examples : Background Processing Return immediately Grails Controller REST service Request Service HTTP Request Trigger ‘request’ event (async) Long REST call @glaforge — @smaldini / #DV13-rtweb !62
  63. 63. Grails — Sending Events (grails-platform-core) def  user  =  new  User(params).save()   ! event('mailRegistration',  user)       //event('mailRegistration',  user).waitFor()       //event  topic:'mailRegistration',  data:user       //event  topic:'mailRegistration',  data:user,  fork:false       render(view:'sendingRegistrationMail') @glaforge — @smaldini / #DV13-rtweb !63
  64. 64. Grails — Sending Events (grails-events) def  user  =  new  User(params).save()   ! event('mailRegistration',  user)                 event('mailRegistration',  user)  {          if(it  ==  ‘end')  {                  cancel()          }   }       Non blocking call to trigger app consumers Do things on each reply Map notation ! //  event  key:  'mailRegistration',  data:  user   ! render(view:  'sendingRegistrationMail') @glaforge — @smaldini / #DV13-rtweb !64
  65. 65. Grails — Consuming Events (grails-platform-core) class  UserService{          @grails.events.Listener          def  mailRegistration(User  user)  {                  sendMail  {                          to  user.mail                          subject  "Confirmation"                          html  g.render(template:"userMailConfirmation")                  }          }   !        @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")                  }          }   } @glaforge — @smaldini / #DV13-rtweb !65
  66. 66. Grails — Consuming Events (grails-events) Consume on Selector(method name) class  UserService{              @reactor.spring.annotation.Selector          def  mailRegistration(User  user){                  sendMail{                          to  user.mail                          subject  "Confirmation"                          html  g.render(template:  "userMailConfirmation")                  }          }   Consume on this specific topic !        @reactor.spring.annotation.Selector("mailRegistration")          def  mailRegistration2(reactor.event.Event  msg){                  sendMail{                          to  msg.data.mail                          subject  "Confirmation"                          html  g.render(template:"userMailConfirmation")                  }          }   } @glaforge — @smaldini / #DV13-rtweb Event typed signature to inspect enveloppe (‘headers…) !66
  67. 67. Grails — A new Artifact conf/XxxxEvents includes  =  ['default']   Merge with DefaultsEvents ! doWithReactor  =  {          reactor(EventsApi.GRAILS_REACTOR)  {                  on('someTopic')  {                          reply  'test'                                          }                                                                                                        }                                                                                                                                        reactor(‘someGormReactor')  {                                                                                                            dispatcher  =  new  SynchronousDispatcher()                  ext  'gorm',  true                                                                                                                   Build a GroovyEnvironment Reactor Groovy Builders ! Grails extension: accept GORM events                stream  {                          consume  {                                  log.info  "Some  gorm  event  is  flowing  with  data  $it.data"                          }.when(Throwable)  {                                  log.error  "Ow  snap!",  it                          }                                                                                                                                                        }                                                      }                                                                                                                                                         } @glaforge — @smaldini / #DV13-rtweb !67
  68. 68. Grails — Reactor awesomeness : Selectors • Listen for arbitrary keys • import static reactor.event.selector.Selectors.* on(T(SpecificClassType))  {   Listen for SpecificClassType                reply  it                                   }                                                                                                 ! Send using right key type event(new  SpecificClassType(),  'data')                                                           ! ! Listen for an URI on(uri(‘/some/{captureIt}'))  {                                                                                          reply  it.headers.captureIt   }                                                                                                                                     ! Send using matching URI event('/some/hourray',  'data')         @glaforge — @smaldini / #DV13-rtweb !68
  69. 69. Grails — Reactor awesomeness : Stream API • Reactive Extensions programming style • Avoid callback hell Build a Stream to capture any reply $(‘test’) consumers may reply withStream  {          event(key:  'test',  data:  1)   }.when(Exception,  {   If a consumer fails        log.info  "exception:$it"   }).map  {   Transform result        callExternalService(it)   }.consume('clientKey',  reactor('browser')) Reroute to key ‘clientKey’ on Reactor ‘browser’ @glaforge — @smaldini / #DV13-rtweb !69
  70. 70. Grails — Reactor awesomeness: Promise API • Grails 2.3 Promises become a Reactor Promises • Benefits from Dispatcher overriding • Powerful once Combined with Consumers dispatcher(ReactorPromise.PromiseDispatcher)  {          type  =  DispatcherType.RingBuffer          backlog  =  512   } task  {          def  res  =   longProcessing()          render  res   } @glaforge — @smaldini / #DV13-rtweb !70
  71. 71. Grails — Reactor awesomeness : Routing • During event dispatching, consumers list is selected • Publish Subscribe is the default • Possible to assign different routing strategy reactor('test1')  {          routingStrategy  'round-­‐robin'          on('test')  {                  reply  '1'   Will reply 1, 2, 1, 2, 1, 2…        }                        on('test')  {                  reply  '2'          }                 } @glaforge — @smaldini / #DV13-rtweb !71
  72. 72. Grails — Extensibility ! • Main extension points: – Dispatcher, Selector, Registry, EventRouter, Consumer ! • Metadata in Reactor Events DSL: – ext(‘someExtension’, [ ‘doStuff’: true ]) @glaforge — @smaldini / #DV13-rtweb !72
  73. 73. Grails — 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 reactor('someGormReactor'){          dispatcher  =  new  SynchronousDispatcher()          ext  'gorm',  true   @Selector(reactor  =  'someGormReactor')   }     @ReplyTo   boolean  beforeValidate(Book  b){          false   } @glaforge — @smaldini / #DV13-rtweb !73
  74. 74. GRAILS-­‐EVENTS-­‐PUSH  plugin Eventing over HTTP! @glaforge — @smaldini / #DV13-rtweb !74
  75. 75. Grails — Pattern Examples : “Realtime” web Push reply to browser: Websocket, SSE, long-polling… Reply a new event ResponseService Browser Return immediately @glaforge — @smaldini / #DV13-rtweb Grails Controller RequestService Trigger async event !75
  76. 76. Grails — 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 @glaforge — @smaldini / #DV13-rtweb !76
  77. 77. Grails — Installing Grails Events Push 1. Install Grails Events plugin 2. Install Grails Events Push plugin grails.servlet.version  =  "3.0"   grails.tomcat.nio  =  true   ! Use a “long-connection” friendly tomcat configuration grails.project.dependency.resolution  =  {          repositories  {          //...                  mavenRepo  "https://oss.sonatype.org/content/repositories/snapshots"          }                                            dependencies  {                                  //...                                                    compile  'org.grails.plugins:events:1.0.0.BUILD-­‐SNAPSHOT'          }                                                                                            plugins  {                                                                                            //...                                                                                                    runtime  ":jquery:1.10.2"                                                                                                                                  runtime  ":events-­‐push:1.0.0.BUILD-­‐SNAPSHOT"                                                }   } @glaforge — @smaldini / #DV13-rtweb !77
  78. 78. Grails — grails-events-push Lifecycle 1 - Handshake Browser EventsPushHandler Adapt Protocol and Open new persistent connection @glaforge — @smaldini / #DV13-rtweb !78
  79. 79. Grails — grails-events-push Lifecycle 2 - Register Consumer registered on all Reactor with ‘browser’ extension enabled Browser Reactor(s) Bridge a Client Consumer with a remote Reactor Consumer @glaforge — @smaldini / #DV13-rtweb !79
  80. 80. Grails — grails-events-push Lifecycle 3 - Notify RequestService consumes on matching Selector within the ‘browser’ Reactor Browser ‘browser’ Reactor RequestService Notify any key @glaforge — @smaldini / #DV13-rtweb !80
  81. 81. Grails — grails-events-push Lifecycle 4 - Consume Notify ‘browser’ enabled Reactor and match key Browser Reactor(s) ResponseService Push event (WS, SSE…) @glaforge — @smaldini / #DV13-rtweb !81
  82. 82. Grails — Generating Simple Browsers bridges includes  =  'push'   ! Conventional name to override ‘browser’ reactor doWithReactor  =  {          reactor('browser')  {                  ext  'browser',  [                          'control',                          'move',                          'fire',                          'leave'                  ]          }          reactor(‘grailsReactor')  {                  ext  'browser',  ['sleepBrowser']   Bridge browser to these reactor consumers $(‘control),… !                stream(‘sleepBrowser')  {                          filter  {                                    it.data  ==  'no'                          }                  }          }   } @glaforge — @smaldini / #DV13-rtweb Bridge browser to this reactor consumer $(‘sleepBrowser) Prevent data ‘no’ to be dispatched to browser bridges !82
  83. 83. Grails — React on server side events Inject grailsEvents.js (requires resources plugin) Create a connection between the browser and the current Grails app Listen for $(‘afterInsert’) events @glaforge — @smaldini / #DV13-rtweb !83
  84. 84. Grails — Generating Advanced Browsers bridges includes  =  ['push']   ! Include PushEvents (configure a reactor for events from Browsers) doWithReactor  =  {          reactor(‘grailsReactor')  {                  ext  'gorm',  true                            ext  'browser',  [                                                                                                                                        'test':  true,                      'afterInsert':  [                                        browserFilter:  {m,  r  -­‐>  true  }                                                                                            ],                                                                                                                                                            (R("sampleBro-­‐.*"))  :  true,                  ]                                                                                                                                                      }                                                                                                                                                              reactor(EventsPushConstants.FROM_BROWSERS)  {                  ext  'browser',  [R("sampleBro-­‐.*")]                                                                                    }                                                                                                             }   Listen on GORM events Extension to bridge Browsers consumers to Server-side pair Events are only routed, from Browsers to bridged Browsers @glaforge — @smaldini / #DV13-rtweb Override “From Browsers” reactor and bridge consumers !84
  85. 85. Grails — 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 @glaforge — @smaldini / #DV13-rtweb !85
  86. 86. Grails — 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 : – Add support for replyTo – extract to standalone module : reactor-atmosphere @glaforge — @smaldini / #DV13-rtweb !86
  87. 87. Grails — Roadmap • events-sockjs: – Involves Reactor work here ! • events-si: – Supports new events plugin ! • events-xx: – The plugin where you are the hero @glaforge — @smaldini / #DV13-rtweb !87
  88. 88. Demo
  89. 89. 4 t r a P Summary
  90. 90. Groovy, Reactor, Grails and the realtime web • Embrace modern reactive architectures with Groovy, Reactor and Grails! • Groovy is a versatile language, that enables development of concise and functional oriented applications • Reactor fuels your asynchronous and reactive applications with its ultra fast dispatching engine and non-blocking model. • Grails supports your today's and tomorrow's web app design, tooled with the right plugins you are prepared for responsive and interactive applications @glaforge — @smaldini / #DV13-rtweb !90

×